Taa, achọrọ m iweta ndị na-agụ Habr nwere akụrụngwa edere na Python maka ịrụ ọrụ dabere na tebụl na PostgreSQL DBMS.
API ngwa ọrụ dị mfe ma nwee ụzọ atọ:
- Archive_table - idekọ ndekọ/ihichapụ ahịrị ndị nwere igodo izizi akọwapụtara
- nweta_table_reference - chọọ ihe ndabere maka tebụl (ga-egosi tebụl nke akọwapụtara na ndị na-ekwu ya)
- nweta ntụaka_rows - chọọ ahịrị na tebụl ndị ọzọ na-ezo aka n'ahịrị ndị akọwapụtara na tebụl achọrọ
prehistory
Aha m bụ Oleg Borzov, abụ m onye nrụpụta na otu CRM maka ndị na-ahụ maka ịgbazinye ego na Domklik.
Isi nchekwa data nke usoro CRM anyị bụ otu n'ime ndị kasị ibu n'ihe gbasara olu na ụlọ ọrụ. Ọ bụkwa otu n'ime ndị kasị ochie: ọ pụtara na mmalite nke oru ngo, mgbe osisi ndị buru ibu, Domklik bụ mmalite, na kama a microservice na a fashionable Python asynchronous framework e nwere nnukwu monolith na PHP.
Mgbanwe site na PHP gaa Python dị ogologo ma chọọ nkwado nke sistemu abụọ a n'otu oge, nke metụtara imewe nchekwa data.
N'ihi ya, anyị nwere nchekwa data nwere ọnụ ọgụgụ buru ibu nke nwere njikọ dị ukwuu na nnukwu tebụl nwere ụyọkọ indexes maka ụdị ajụjụ dị iche iche. Ihe a niile na-emetụta arụmọrụ nke nchekwa data na-adịghị mma: n'ihi nnukwu tebụl na ụyọkọ mmekọrịta dị n'etiti ha, mgbagwoju anya nke ajụjụ na-arịwanye elu mgbe niile, nke dị oke mkpa maka tebụl ndị kacha ibu.
Iji belata ibu dị na nchekwa data, anyị kpebiri ide edemede nke ga-ebufe ihe ndekọ ochie site na tebụl ndị kachasị ụda na nke a na-ebunye na ndị echekwara (dịka ọmụmaatụ, site na. task
в task_archive
).
Ọrụ a gbagwojuru anya site na ọnụ ọgụgụ dị ukwuu nke mmekọrịta dị n'etiti tebụl: naanị bugharịa ahịrị site na task
в task_archive
ezughị ezu, tupu nke ahụ ịkwesịrị ime otu ihe ahụ recursively na ndị niile na-ezo aka task
tebụl.
M ga-eji ihe atụ gosi
Ka anyị kwuo na anyị kwesịrị ihichapụ ndekọ na tebụl Flights
. Postgres agaghị ekwe ka anyị mee nke a dị ka nke ahụ: anyị kwesịrị ibu ụzọ ihichapụ ihe ndekọ na tebụl nrụtụ aka niile, na ihe ndị ọzọ na-aga n'ihu na tebụl ndị na-adịghị onye ọ bụla kwuru.
N'ihe atụ anyị na Flights
na-ezo aka Ticket_flights
na ya - Boarding_passes
.
Ya mere, ị ga-ehichapụ ya n'usoro a:
- Anyị na-enweta uru igodo mbụ (PK) nke ahịrị
Ticket_flights
, nke na-ezo aka na ahịrị ndị a ga-ehichapụ naFlights
. - Anyị na-enweta ahịrị PK
Boarding_passes
, nke na-ezo akaTicket_flights
. - Anyị na-ehichapụ ahịrị site na PK site na nzọụkwụ 2 na tebụl
Boarding_passes
. - Hichapụ ahịrị site na PK site na nzọụkwụ 1 in
Ticket_flights
. - Na-ewepu ahịrị si
Flights
.
Nsonaazụ bụ akụrụngwa akpọrọ PgGraph, nke anyị kpebiri ime oghere mepere emepe.
Otu esi eji
Ngwa ahụ na-akwado ụdị ojiji abụọ:
- Kpọọ site na ahịrị iwu (
pggraph …
). - Ojiji na koodu Python (klas
PgGraphApi
).
Ntinye na nhazi
Mbụ ị ga-achọ ịwụnye akụrụngwa site na ebe nchekwa Pypi:
pip3 install pggraph
Wee mepụta faịlụ config.ini na igwe mpaghara yana nhazi nke nchekwa data yana edemede nchekwa:
[db]
host = localhost
port = 5432
user = postgres
password = postgres
dbname = postgres
schema = public ; Необязательный параметр, указано значение по умолчанию
[archive] ; Данный раздел заполнять необязательно, ниже указаны значения по умолчанию
is_debug = false
chunk_size = 1000
max_depth = 20
to_archive = true
archive_suffix = 'archive'
Gbaa na console
parameters
$ pggraph -h
usage: pggraph action [-h] --table TABLE [--ids IDS] [--config_path CONFIG_PATH]
positional arguments:
action required action: archive_table, get_table_references, get_rows_references
optional arguments:
-h, --help show this help message and exit
--table TABLE table name
--ids IDS primary key ids, separated by comma, e.g. 1,2,3
--config_path CONFIG_PATH path to config.ini
--log_path LOG_PATH path to log dir
--log_level LOG_LEVEL log level (debug, info, error)
Esemokwu ọnọdụ:
action
- ihe achọrọ:archive_table
,get_table_references
ma ọ bụget_rows_references
.
Arụmụka akpọrọ aha:
--config_path
- ụzọ na faịlụ nhazi;--table
- tebụl nke ị chọrọ iji mee ihe;--ids
- ndepụta id nke rịkọm kewapụrụ, dịka ọmụmaatụ,1,2,3
(nhọrọ oke);--log_path
- ụzọ na nchekwa maka ndekọ (nhọrọ oke, ndabara - nchekwa ụlọ);--log_level
- ọkwa ndekọ (nhọrọ oke, ndabara bụ INFO).
Ihe atụ iwu
Ịdebe tebụl
Isi ọrụ nke akụrụngwa bụ nchekwa data, ya bụ. na-ebufe ahịrị site na tebụl isi gaa na tebụl ebe nchekwa (dịka ọmụmaatụ, site na tebụl akwụkwọ в akwụkwọ_nchekwa).
A na-akwadokwa ihichapụ na-enweghị ebe nchekwa: maka nke a ịkwesịrị ịtọ paramita na config.ini to_archive = ụgha).
Ihe ndị achọrọ - config_path, tebụl na ids.
Mgbe emepechara, a ga-ehichapụ ndekọ ugboro ugboro ids
na tebụl table
na na tebụl niile na-ezo aka na ya.
$ pggraph archive_table --config_path config.hw.local.ini --table flights --ids 1,2,3
2020-06-20 19:27:44 INFO: flights - START
2020-06-20 19:27:44 INFO: flights - start archive_recursive 3 rows (depth=0)
2020-06-20 19:27:44 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: ticket_flights - start archive_recursive 3 rows (depth=1)
2020-06-20 19:27:44 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: boarding_passes - start archive_recursive 3 rows (depth=2)
2020-06-20 19:27:44 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: boarding_passes - archive_by_ids 3 rows by ticket_no, flight_id
2020-06-20 19:27:44 INFO: boarding_passes - start archive_recursive 3 rows (depth=2)
2020-06-20 19:27:44 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: boarding_passes - archive_by_ids 3 rows by ticket_no, flight_id
2020-06-20 19:27:44 INFO: boarding_passes - start archive_recursive 3 rows (depth=2)
2020-06-20 19:27:44 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: boarding_passes - archive_by_ids 3 rows by ticket_no, flight_id
2020-06-20 19:27:44 INFO: boarding_passes - start archive_recursive 3 rows (depth=2)
2020-06-20 19:27:44 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: boarding_passes - archive_by_ids 3 rows by ticket_no, flight_id
2020-06-20 19:27:44 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: ticket_flights - archive_by_ids 3 rows by ticket_no, flight_id
2020-06-20 19:27:44 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 19:27:44 INFO: flights - archive_by_ids 3 rows by id
2020-06-20 19:27:44 INFO: flights - END
Chọta ndabere maka tebụl akọwapụtara
Ọrụ ịchọta ndabere nke tebụl akọwapụtara table
. Ihe ndị achọrọ - config_path
и table
.
Mgbe emepechara, a ga-egosipụta ọkọwa okwu na ihuenyo, ebe:
in_refs
- akwụkwọ ọkọwa okwu nke tebụl na-ezo aka nyere otu, ebe igodo bụ aha tebụl, uru bụ ndepụta nke ihe ndị mba ọzọ (pk_main
- isi igodo na tebụl isi,pk_ref
- isi igodo na tebụl ntụaka,fk_ref
- aha nke kọlụm nke bụ igodo mba ọzọ na tebụl isi iyi);out_refs
- akwụkwọ ọkọwa okwu nke tebụl nke a na-ezo aka na ya.
$ pggraph get_table_references --config_path config.hw.local.ini --table flights
{'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')]}}
Ịchọta ntụaka maka eriri nwere igodo isi akọwapụtara
Ọrụ iji chọọ ahịrị na tebụl ndị ọzọ na-ezo aka na ahịrị site na igodo mba ofesi ids
tebụl table
. Ihe ndị achọrọ - config_path
, table
и ids
.
Mgbe emepechara, a ga-egosipụta ọkọwa okwu nwere usoro a na ihuenyo:
{
pk_id_1: {
reffering_table_name_1: {
foreign_key_1: [
{row_pk_1: value, row_pk_2: value},
...
],
...
},
...
},
pk_id_2: {...},
...
}
Ọmụmaatụ oku:
$ pggraph get_rows_references --config_path config.hw.local.ini --table flights --ids 1,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'}]}}}
Ojiji na koodu
Na mgbakwunye na ịgba ya na njikwa, enwere ike iji ọba akwụkwọ na koodu Python. Ihe atụ nke oku na mpaghara mmekọrịta iPython ka egosiri n'okpuru.
Ịdebe tebụl
>>> from pg_graph.main import setup_logging
>>> setup_logging(log_level='DEBUG')
>>> from pg_graph.api import PgGraphApi
>>> api = PgGraphApi('config.hw.local.ini')
>>> api.archive_table('flights', [4,5])
2020-06-20 23:12:08 INFO: flights - START
2020-06-20 23:12:08 INFO: flights - start archive_recursive 2 rows (depth=0)
2020-06-20 23:12:08 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 DEBUG: ticket_flights - ForeignKey(pk_main='flight_id', pk_ref='flight_id, ticket_no', fk_ref='flight_id')
2020-06-20 23:12:08 DEBUG: SQL('SELECT flight_id, ticket_no FROM bookings.ticket_flights WHERE (flight_id) IN (%s, %s)')
2020-06-20 23:12:08 INFO: ticket_flights - start archive_recursive 30 rows (depth=1)
2020-06-20 23:12:08 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 DEBUG: boarding_passes - ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 INFO: boarding_passes - archive_by_fk 30 rows by ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')
2020-06-20 23:12:08 DEBUG: DELETE FROM boarding_passes by FK flight_id, ticket_no - 30 rows
2020-06-20 23:12:08 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 INFO: ticket_flights - archive_by_ids 30 rows by flight_id, ticket_no
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')
2020-06-20 23:12:08 DEBUG: DELETE FROM ticket_flights by flight_id, ticket_no - 30 rows
2020-06-20 23:12:08 DEBUG: INSERT INTO ticket_flights_archive - 30 rows
2020-06-20 23:12:08 INFO: ticket_flights - start archive_recursive 30 rows (depth=1)
2020-06-20 23:12:08 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 DEBUG: boarding_passes - ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 INFO: boarding_passes - archive_by_fk 30 rows by ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')
2020-06-20 23:12:08 DEBUG: DELETE FROM boarding_passes by FK flight_id, ticket_no - 30 rows
2020-06-20 23:12:08 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 INFO: ticket_flights - archive_by_ids 30 rows by flight_id, ticket_no
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')
2020-06-20 23:12:08 DEBUG: DELETE FROM ticket_flights by flight_id, ticket_no - 30 rows
2020-06-20 23:12:08 DEBUG: INSERT INTO ticket_flights_archive - 30 rows
2020-06-20 23:12:08 INFO: ticket_flights - start archive_recursive 30 rows (depth=1)
2020-06-20 23:12:08 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 DEBUG: boarding_passes - ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 INFO: boarding_passes - archive_by_fk 30 rows by ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')
2020-06-20 23:12:08 DEBUG: DELETE FROM boarding_passes by FK flight_id, ticket_no - 30 rows
2020-06-20 23:12:08 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 INFO: ticket_flights - archive_by_ids 30 rows by flight_id, ticket_no
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')
2020-06-20 23:12:08 DEBUG: DELETE FROM ticket_flights by flight_id, ticket_no - 30 rows
2020-06-20 23:12:08 DEBUG: INSERT INTO ticket_flights_archive - 30 rows
2020-06-20 23:12:08 INFO: ticket_flights - start archive_recursive 3 rows (depth=1)
2020-06-20 23:12:08 INFO: START ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 DEBUG: boarding_passes - ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 INFO: boarding_passes - archive_by_fk 3 rows by ForeignKey(pk_main='flight_id, ticket_no', pk_ref='flight_id, ticket_no', fk_ref='flight_id, ticket_no')
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.boarding_passes_archive (LIKE bookings.boarding_passes)')
2020-06-20 23:12:08 DEBUG: DELETE FROM boarding_passes by FK flight_id, ticket_no - 3 rows
2020-06-20 23:12:08 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 INFO: ticket_flights - archive_by_ids 3 rows by flight_id, ticket_no
2020-06-20 23:12:08 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.ticket_flights_archive (LIKE bookings.ticket_flights)')
2020-06-20 23:12:08 DEBUG: DELETE FROM ticket_flights by flight_id, ticket_no - 3 rows
2020-06-20 23:12:08 DEBUG: INSERT INTO ticket_flights_archive - 3 rows
2020-06-20 23:12:08 INFO: END ARCHIVE REFERRING TABLES
2020-06-20 23:12:08 INFO: flights - archive_by_ids 2 rows by flight_id
2020-06-20 23:12:09 DEBUG: SQL('CREATE TABLE IF NOT EXISTS bookings.flights_archive (LIKE bookings.flights)')
2020-06-20 23:12:09 DEBUG: DELETE FROM flights by flight_id - 2 rows
2020-06-20 23:12:09 DEBUG: INSERT INTO flights_archive - 2 rows
2020-06-20 23:12:09 INFO: flights - END
Chọta ndabere maka tebụl akọwapụtara
>>> from pg_graph.api import PgGraphApi
>>> from pprint import pprint
>>> api = PgGraphApi('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')]}}
Ịchọta ntụaka maka eriri nwere igodo isi akọwapụtara
>>> from pg_graph.api import PgGraphApi
>>> from pprint import pprint
>>> api = PgGraphApi('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'}]}}}
Koodu isi mmalite ọba akwụkwọ dị na
Ọ ga-amasị m ịza ajụjụ, ntinye aka na aro.
M ga-agbalị ịza ajụjụ niile ike m ebe a na ebe nchekwa.
isi: www.habr.com