Package: pggraph
PgGraphУтилита для работы с зависимостями таблиц в PostgreSQLОсновной функционал:Рекурсивное удаление и архивация строк в таблице с указанными Primary KeyПод архивацией понимается перенос строк в архивную таблицу (например, из "books" в "books_archive")Поиск зависимостей для указанной таблицы (ссылающиеся таблицы и таблицы на которые ссылается данная)Поиск ссылок на строки с указанными Primary Key данной таблицыУстановка$ pip install pggraphФайл конфигурации config.iniДля работы утилиты нужно создать на локальной машине конфигурационный файл config.ini со следующим содержимым:[db]host=localhostport=5432user=postgrespassword=postgresdbname=postgresschema=public; Необязательный параметр, указано значение по умолчанию[archive]                       ; Данный раздел заполнять необязательно, ниже указаны значения по умолчаниюis_debug=false; Запуск в режиме debug (удаление из таблицы происходить не будет)chunk_size=1000; Кол-во строк, которое архивируется за 1 шагmax_depth=20; Максимальная глубина рекурсииto_archive=true; Режим архивации (строки из таблицы "a" переносятся в таблицу "a_%archive_suffix%")archive_suffix='archive'; Суффикс архивной таблицыСтруктураcore- основной функционалdb- функции и классы для работы с БДarchiver.py - Archiver - класс с функционалом архивации таблицbuild_references.py - построение графа зависимостей между таблицамиutils- вспомогательные функции и классыapi.py - PgGraphApi, основной класс для работыconfig.py - парсинг конфигурацииКоманды для запускаУтилиту можно запускать из консоли, также с ней можно работать из кода или интерактивных оболочек, вроде IPython/JupyterLab.Запуск из консолиПараметрыПозиционные аргументы:action - требуемое действие: archive_table, get_table_references или get_rows_referencesИменованные аргументы:--config_path - путь к конфиг-файлу--table - таблица с которой нужно совершить действие--ids - список id через запятую, пример - 1,2,3 (необязательный параметр)--log_path - путь к папке для логов (необязательный параметр, по умолчанию - None)--log_level - уровень логирования (необязательный параметр, по умолчанию - INFO)$pggraph-h
usage:pggraphaction[-h]--tableTABLE[--idsIDS][--config_pathCONFIG_PATH]positionalarguments:actionrequiredaction:archive_table,get_table_references,get_rows_references

optionalarguments:-h,--helpshowthishelpmessageandexit--tableTABLEtablename--idsIDSprimarykeyids,separatedbycomma,e.g.1,2,3--config_pathCONFIG_PATHpathtoconfig.ini--log_pathLOG_PATHpathtologdir--log_levelLOG_LEVELloglevel(debug,info,error)Примеры командАрхивация таблицы$pggrapharchive_table--config_pathconfig.hw.local.ini--tableflights--ids1,2,32020-06-2019:27:44INFO:flights-START2020-06-2019:27:44INFO:flights-startarchive_recursive3rows(depth=0)2020-06-2019:27:44INFO:STARTARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:ticket_flights-startarchive_recursive3rows(depth=1)2020-06-2019:27:44INFO:STARTARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:boarding_passes-startarchive_recursive3rows(depth=2)2020-06-2019:27:44INFO:STARTARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:ENDARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:boarding_passes-archive_by_ids3rowsbyticket_no,flight_id2020-06-2019:27:44INFO:boarding_passes-startarchive_recursive3rows(depth=2)2020-06-2019:27:44INFO:STARTARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:ENDARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:boarding_passes-archive_by_ids3rowsbyticket_no,flight_id2020-06-2019:27:44INFO:boarding_passes-startarchive_recursive3rows(depth=2)2020-06-2019:27:44INFO:STARTARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:ENDARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:boarding_passes-archive_by_ids3rowsbyticket_no,flight_id2020-06-2019:27:44INFO:boarding_passes-startarchive_recursive3rows(depth=2)2020-06-2019:27:44INFO:STARTARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:ENDARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:boarding_passes-archive_by_ids3rowsbyticket_no,flight_id2020-06-2019:27:44INFO:ENDARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:ticket_flights-archive_by_ids3rowsbyticket_no,flight_id2020-06-2019:27:44INFO:ENDARCHIVEREFERRINGTABLES2020-06-2019:27:44INFO:flights-archive_by_ids3rowsbyid2020-06-2019:27:44INFO:flights-ENDПоиск зависимостей для указанной таблицы$pggraphget_table_references--config_pathconfig.hw.local.ini--tableflights{'in_refs':{'ticket_flights':[ForeignKey(pk_main='flight_id',pk_ref='ticket_no, flight_id',fk_ref='flight_id')]},'out_refs':{'aircrafts':[ForeignKey(pk_main='aircraft_code',pk_ref='flight_id',fk_ref='aircraft_code')],'airports':[ForeignKey(pk_main='airport_code',pk_ref='flight_id',fk_ref='arrival_airport'),ForeignKey(pk_main='airport_code',pk_ref='flight_id',fk_ref='departure_airport')]}}Поиск ссылок на строки с указанными Primary Key$pggraphget_rows_references--config_pathconfig.hw.local.ini--tableflights--ids1,2,3{1:{'ticket_flights':{'flight_id':[{'flight_id':1,'ticket_no':'0005432816945'},{'flight_id':1,'ticket_no':'0005432816941'}]}},2:{'ticket_flights':{'flight_id':[{'flight_id':2,'ticket_no':'0005433101832'},{'flight_id':2,'ticket_no':'0005433101864'},{'flight_id':2,'ticket_no':'0005432919715'}]}},3:{'ticket_flights':{'flight_id':[{'flight_id':3,'ticket_no':'0005432817560'},{'flight_id':3,'ticket_no':'0005432817568'},{'flight_id':3,'ticket_no':'0005432817559'}]}}}Работа в интерактивной консоли iPythonАрхивация таблицы>>>frompggraph.mainimportsetup_logging>>>setup_logging(log_level='DEBUG')>>>frompggraph.apiimportPgGraphApi>>>api=PgGraphApi(config_path='config.hw.local.ini')>>>api.archive_table('flights',[4,5])2020-06-2023:12:08INFO:flights-START2020-06-2023:12:08INFO:flights-startarchive_recursive2rows(depth=0)2020-06-2023:12:08INFO:STARTARCHIVEREFERRINGTABLES2020-06-2023:12:08DEBUG:ticket_flights-ForeignKey(pk_main='flight_id',pk_ref='flight_id, ticket_no',fk_ref='flight_id')2020-06-2023:12:08DEBUG:SQL('SELECT flight_id, ticket_no FROM bookings.ticket_flights WHERE (flight_id) IN (%s,%s)')2020-06-2023:12:08INFO:ticket_flights-startarchive_recursive30rows(depth=1)2020-06-2023:12:08INFO:STARTARCHIVEREFERRINGTABLES2020-06-2023:12:08DEBUG:boarding_passes-ForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08INFO:boarding_passes-archive_by_fk30rowsbyForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')2020-06-2023:12:08DEBUG:DELETEFROMboarding_passesbyFKflight_id,ticket_no-30rows2020-06-2023:12:08INFO:ENDARCHIVEREFERRINGTABLES2020-06-2023:12:08INFO:ticket_flights-archive_by_ids30rowsbyflight_id,ticket_no2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')2020-06-2023:12:08DEBUG:DELETEFROMticket_flightsbyflight_id,ticket_no-30rows2020-06-2023:12:08DEBUG:INSERTINTOticket_flights_archive-30rows2020-06-2023:12:08INFO:ticket_flights-startarchive_recursive30rows(depth=1)2020-06-2023:12:08INFO:STARTARCHIVEREFERRINGTABLES2020-06-2023:12:08DEBUG:boarding_passes-ForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08INFO:boarding_passes-archive_by_fk30rowsbyForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')2020-06-2023:12:08DEBUG:DELETEFROMboarding_passesbyFKflight_id,ticket_no-30rows2020-06-2023:12:08INFO:ENDARCHIVEREFERRINGTABLES2020-06-2023:12:08INFO:ticket_flights-archive_by_ids30rowsbyflight_id,ticket_no2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')2020-06-2023:12:08DEBUG:DELETEFROMticket_flightsbyflight_id,ticket_no-30rows2020-06-2023:12:08DEBUG:INSERTINTOticket_flights_archive-30rows2020-06-2023:12:08INFO:ticket_flights-startarchive_recursive30rows(depth=1)2020-06-2023:12:08INFO:STARTARCHIVEREFERRINGTABLES2020-06-2023:12:08DEBUG:boarding_passes-ForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08INFO:boarding_passes-archive_by_fk30rowsbyForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')2020-06-2023:12:08DEBUG:DELETEFROMboarding_passesbyFKflight_id,ticket_no-30rows2020-06-2023:12:08INFO:ENDARCHIVEREFERRINGTABLES2020-06-2023:12:08INFO:ticket_flights-archive_by_ids30rowsbyflight_id,ticket_no2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')2020-06-2023:12:08DEBUG:DELETEFROMticket_flightsbyflight_id,ticket_no-30rows2020-06-2023:12:08DEBUG:INSERTINTOticket_flights_archive-30rows2020-06-2023:12:08INFO:ticket_flights-startarchive_recursive3rows(depth=1)2020-06-2023:12:08INFO:STARTARCHIVEREFERRINGTABLES2020-06-2023:12:08DEBUG:boarding_passes-ForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08INFO:boarding_passes-archive_by_fk3rowsbyForeignKey(pk_main='flight_id, ticket_no',pk_ref='flight_id, ticket_no',fk_ref='flight_id, ticket_no')2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')2020-06-2023:12:08DEBUG:DELETEFROMboarding_passesbyFKflight_id,ticket_no-3rows2020-06-2023:12:08INFO:ENDARCHIVEREFERRINGTABLES2020-06-2023:12:08INFO:ticket_flights-archive_by_ids3rowsbyflight_id,ticket_no2020-06-2023:12:08DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')2020-06-2023:12:08DEBUG:DELETEFROMticket_flightsbyflight_id,ticket_no-3rows2020-06-2023:12:08DEBUG:INSERTINTOticket_flights_archive-3rows2020-06-2023:12:08INFO:ENDARCHIVEREFERRINGTABLES2020-06-2023:12:08INFO:flights-archive_by_ids2rowsbyflight_id2020-06-2023:12:09DEBUG:SQL('CREATE TABLE IF NOT EXISTS bookings.flights_archive (LIKE bookings.flights)')2020-06-2023:12:09DEBUG:DELETEFROMflightsbyflight_id-2rows2020-06-2023:12:09DEBUG:INSERTINTOflights_archive-2rows2020-06-2023:12:09INFO:flights-ENDПоиск зависимостей для указанной таблицы>>>frompggraph.apiimportPgGraphApi>>>frompprintimportpprint>>>api=PgGraphApi(config_path='config.hw.local.ini')>>>res=api.get_table_references('flights')>>>pprint(res){'in_refs':{'ticket_flights':[ForeignKey(pk_main='flight_id',pk_ref='flight_id, ticket_no',fk_ref='flight_id')]},'out_refs':{'aircrafts':[ForeignKey(pk_main='aircraft_code',pk_ref='flight_id',fk_ref='aircraft_code')],'airports':[ForeignKey(pk_main='airport_code',pk_ref='flight_id',fk_ref='arrival_airport'),ForeignKey(pk_main='airport_code',pk_ref='flight_id',fk_ref='departure_airport')]}}Поиск ссылок на строки с указанными Primary Key>>>frompggraph.apiimportPgGraphApi>>>frompprintimportpprint>>>api=PgGraphApi(config_path='config.hw.local.ini')>>>rows=api.get_rows_references('flights',[1,2,3])>>>pprint(rows){1:{'ticket_flights':{'flight_id':[{'flight_id':1,'ticket_no':'0005432816945'},{'flight_id':1,'ticket_no':'0005432816941'}]}},2:{'ticket_flights':{'flight_id':[{'flight_id':2,'ticket_no':'0005433101832'},{'flight_id':2,'ticket_no':'0005433101864'},{'flight_id':2,'ticket_no':'0005432919715'}]}},3:{'ticket_flights':{'flight_id':[{'flight_id':3,'ticket_no':'0005432817560'},{'flight_id':3,'ticket_no':'0005432817568'},{'flight_id':3,'ticket_no':'0005432817559'}]}}}AuthorBorzov Oleg(Author)Contributor NoticeWe are always open for contributions. Feel free to submit an issue
or a PR. However, when submitting a PR we will ask you to sign
our [CLA (Contributor License Agreement)][cla-text] to confirm that you
have the rights to submit your contributions and to give us the rights
to actually use them.When submitting a PR our special bot will ask you to review and to sign
our [CLA][cla-text]. This will happen only once for all our GitHub repositories.LicenseCopyright Ⓒ 2020"Sberbank Real Estate Center" Limited Liability Company.MIT License