pgbelt 0.7.1__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pgbelt-0.7.1 → pgbelt-0.7.2}/PKG-INFO +1 -1
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/setup.py +25 -2
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/status.py +8 -1
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/sync.py +16 -2
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/util/postgres.py +41 -5
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pyproject.toml +4 -4
- {pgbelt-0.7.1 → pgbelt-0.7.2}/LICENSE +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/README.md +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/__init__.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/__init__.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/convenience.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/helpers.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/login.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/preflight.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/schema.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/cmd/teardown.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/config/__init__.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/config/config.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/config/models.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/config/remote.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/main.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/util/__init__.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/util/asyncfuncs.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/util/dump.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/util/logs.py +0 -0
- {pgbelt-0.7.1 → pgbelt-0.7.2}/pgbelt/util/pglogical.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pgbelt
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: A CLI tool used to manage Postgres data migrations from beginning to end, for a single database or a fleet, leveraging pglogical replication.
|
|
5
5
|
Author: Varjitt Jeeva
|
|
6
6
|
Author-email: varjitt.jeeva@autodesk.com
|
|
@@ -41,7 +41,23 @@ async def _setup_src_node(
|
|
|
41
41
|
|
|
42
42
|
pglogical_tables = pkey_tables
|
|
43
43
|
if conf.tables:
|
|
44
|
-
pglogical_tables = [
|
|
44
|
+
pglogical_tables = [
|
|
45
|
+
t
|
|
46
|
+
for t in pkey_tables
|
|
47
|
+
if t
|
|
48
|
+
in list(
|
|
49
|
+
map(str.lower, conf.tables)
|
|
50
|
+
) # Postgres returns table names in lowercase (in analyze_table_pkeys)
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# Intentionally throw an error if no tables are found, so that the user can correct their config.
|
|
54
|
+
# When reported by a certain user, errors showed when running the status command, but it was ignored,
|
|
55
|
+
# then the user ran setup and since that DIDN'T throw an error, they assumed everything was fine.
|
|
56
|
+
|
|
57
|
+
if not pglogical_tables:
|
|
58
|
+
raise ValueError(
|
|
59
|
+
f"No tables were targeted to replicate. Please check your config's schema and tables. DB: {conf.db} DC: {conf.dc}, SCHEMA: {conf.schema_name} TABLES: {conf.tables}.\nIf TABLES is [], all tables in the schema should be replicated, but pgbelt still found no tables.\nCheck the schema name or reach out to the pgbelt team for help."
|
|
60
|
+
)
|
|
45
61
|
|
|
46
62
|
await configure_replication_set(
|
|
47
63
|
src_root_pool, pglogical_tables, conf.schema_name, src_logger
|
|
@@ -145,7 +161,14 @@ async def setup_back_replication(config_future: Awaitable[DbupgradeConfig]) -> N
|
|
|
145
161
|
|
|
146
162
|
pglogical_tables = pkeys
|
|
147
163
|
if conf.tables:
|
|
148
|
-
pglogical_tables = [
|
|
164
|
+
pglogical_tables = [
|
|
165
|
+
t
|
|
166
|
+
for t in pkeys
|
|
167
|
+
if t
|
|
168
|
+
in list(
|
|
169
|
+
map(str.lower, conf.tables)
|
|
170
|
+
) # Postgres returns table names in lowercase (in analyze_table_pkeys)
|
|
171
|
+
]
|
|
149
172
|
|
|
150
173
|
await configure_replication_set(
|
|
151
174
|
dst_root_pool, pglogical_tables, conf.schema_name, dst_logger
|
|
@@ -92,7 +92,14 @@ async def status(conf_future: Awaitable[DbupgradeConfig]) -> dict[str, str]:
|
|
|
92
92
|
all_tables = pkey_tables + non_pkey_tables
|
|
93
93
|
target_tables = all_tables
|
|
94
94
|
if conf.tables:
|
|
95
|
-
target_tables = [
|
|
95
|
+
target_tables = [
|
|
96
|
+
t
|
|
97
|
+
for t in all_tables
|
|
98
|
+
if t
|
|
99
|
+
in list(
|
|
100
|
+
map(str.lower, conf.tables)
|
|
101
|
+
) # Postgres gave us lowercase table names in analyze_table_pkeys
|
|
102
|
+
]
|
|
96
103
|
|
|
97
104
|
if not target_tables:
|
|
98
105
|
raise ValueError(
|
|
@@ -77,7 +77,14 @@ async def dump_tables(
|
|
|
77
77
|
_, tables, _ = await analyze_table_pkeys(src_pool, conf.schema_name, logger)
|
|
78
78
|
|
|
79
79
|
if conf.tables:
|
|
80
|
-
tables = [
|
|
80
|
+
tables = [
|
|
81
|
+
t
|
|
82
|
+
for t in tables
|
|
83
|
+
if t
|
|
84
|
+
in list(
|
|
85
|
+
map(str.lower, conf.tables)
|
|
86
|
+
) # Postgres returns table names in lowercase (in analyze_table_pkeys)
|
|
87
|
+
]
|
|
81
88
|
|
|
82
89
|
await dump_source_tables(conf, tables, logger)
|
|
83
90
|
|
|
@@ -185,7 +192,14 @@ async def _dump_and_load_all_tables(
|
|
|
185
192
|
) -> None:
|
|
186
193
|
_, tables, _ = await analyze_table_pkeys(src_pool, conf.schema_name, src_logger)
|
|
187
194
|
if conf.tables:
|
|
188
|
-
tables = [
|
|
195
|
+
tables = [
|
|
196
|
+
t
|
|
197
|
+
for t in tables
|
|
198
|
+
if t
|
|
199
|
+
in list(
|
|
200
|
+
map(str.lower, conf.tables)
|
|
201
|
+
) # Postgres returns table names in lowercase (in analyze_table_pkeys)
|
|
202
|
+
]
|
|
189
203
|
await dump_source_tables(conf, tables, src_logger)
|
|
190
204
|
await load_dumped_tables(conf, tables, dst_logger)
|
|
191
205
|
|
|
@@ -97,10 +97,16 @@ async def compare_data(
|
|
|
97
97
|
dst_old_extra_float_digits = await dst_pool.fetchval("SHOW extra_float_digits;")
|
|
98
98
|
await dst_pool.execute("SET extra_float_digits TO 0;")
|
|
99
99
|
|
|
100
|
+
has_run = False
|
|
100
101
|
for table in set(pkeys):
|
|
101
|
-
# If specific table list is defined and iterated table is not in that list, skip.
|
|
102
|
-
|
|
102
|
+
# If specific table list is defined and the iterated table is not in that list, skip.
|
|
103
|
+
# Note that the pkeys tables returned from Postgres are all lowercased, so we need to
|
|
104
|
+
# map the passed conf tables to lowercase.
|
|
105
|
+
if tables and (table not in list(map(str.lower, tables))):
|
|
103
106
|
continue
|
|
107
|
+
|
|
108
|
+
has_run = True # If this runs, we have at least one table to compare. We will use this flag to throw an error if no tables are found.
|
|
109
|
+
|
|
104
110
|
full_table_name = f"{schema}.{table}"
|
|
105
111
|
|
|
106
112
|
logger.debug(f"Validating table {full_table_name}...")
|
|
@@ -171,6 +177,13 @@ async def compare_data(
|
|
|
171
177
|
f"Dest Row: {dst_row}"
|
|
172
178
|
)
|
|
173
179
|
|
|
180
|
+
# Just a paranoia check. If this throws, then it's possible pgbelt didn't migrate any data.
|
|
181
|
+
# This was found in issue #420, and previous commands threw errors before this issue could arise.
|
|
182
|
+
if not has_run:
|
|
183
|
+
raise ValueError(
|
|
184
|
+
"No tables were found to compare. Please reach out to the pgbelt for help, and check if your data was migrated."
|
|
185
|
+
)
|
|
186
|
+
|
|
174
187
|
await src_pool.execute(f"SET extra_float_digits TO {src_old_extra_float_digits};")
|
|
175
188
|
await dst_pool.execute(f"SET extra_float_digits TO {dst_old_extra_float_digits};")
|
|
176
189
|
logger.info(
|
|
@@ -372,9 +385,22 @@ async def precheck_info(
|
|
|
372
385
|
AND n.nspname <> 'pglogical'
|
|
373
386
|
ORDER BY 1,2;"""
|
|
374
387
|
)
|
|
388
|
+
|
|
375
389
|
# We filter the table list if the user has specified a list of tables to target.
|
|
390
|
+
# Note, from issue #420, the above query will return the table names in lowercase,
|
|
391
|
+
# so we need to map the target_tables to lowercase.
|
|
376
392
|
if target_tables:
|
|
377
|
-
|
|
393
|
+
|
|
394
|
+
result["tables"] = [
|
|
395
|
+
t
|
|
396
|
+
for t in result["tables"]
|
|
397
|
+
if t["Name"] in list(map(str.lower, target_tables))
|
|
398
|
+
]
|
|
399
|
+
|
|
400
|
+
# We will not recapitalize the table names in the result["tables"] list,
|
|
401
|
+
# to preserve how Postgres sees those tables in its system catalog. Easy
|
|
402
|
+
# rabbit hole later if we keep patching the table names to match the user's
|
|
403
|
+
# input.
|
|
378
404
|
|
|
379
405
|
result["sequences"] = await pool.fetch(
|
|
380
406
|
"""
|
|
@@ -392,12 +418,22 @@ async def precheck_info(
|
|
|
392
418
|
ORDER BY 1,2;"""
|
|
393
419
|
)
|
|
394
420
|
|
|
395
|
-
# We filter the
|
|
421
|
+
# We filter the table list if the user has specified a list of tables to target.
|
|
422
|
+
# Note, from issue #420, the above query will return the table names in lowercase,
|
|
423
|
+
# so we need to map the target_tables to lowercase.
|
|
396
424
|
if target_sequences:
|
|
425
|
+
|
|
397
426
|
result["sequences"] = [
|
|
398
|
-
|
|
427
|
+
t
|
|
428
|
+
for t in result["sequences"]
|
|
429
|
+
if t["Name"] in list(map(str.lower, target_sequences))
|
|
399
430
|
]
|
|
400
431
|
|
|
432
|
+
# We will not recapitalize the table names in the result["tables"] list,
|
|
433
|
+
# to preserve how Postgres sees those tables in its system catalog. Easy
|
|
434
|
+
# rabbit hole later if we keep patching the table names to match the user's
|
|
435
|
+
# input.
|
|
436
|
+
|
|
401
437
|
users = await pool.fetch(
|
|
402
438
|
f"""
|
|
403
439
|
SELECT r.rolname, r.rolsuper, r.rolinherit,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pgbelt"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.2"
|
|
4
4
|
description = "A CLI tool used to manage Postgres data migrations from beginning to end, for a single database or a fleet, leveraging pglogical replication."
|
|
5
5
|
authors = ["Varjitt Jeeva <varjitt.jeeva@autodesk.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -18,14 +18,14 @@ tabulate = "^0.9.0"
|
|
|
18
18
|
typer = "^0.9.0"
|
|
19
19
|
|
|
20
20
|
[tool.poetry.dev-dependencies]
|
|
21
|
-
black = "~24.
|
|
21
|
+
black = "~24.3.0"
|
|
22
22
|
pre-commit = "~3.6.2"
|
|
23
23
|
flake8 = "^7.0.0"
|
|
24
24
|
pytest-cov = "~4.1.0"
|
|
25
|
-
pytest = "^8.
|
|
25
|
+
pytest = "^8.1.1"
|
|
26
26
|
coverage = {extras = ["toml"], version = "^7.4"}
|
|
27
27
|
safety = "^2.3.1"
|
|
28
|
-
mypy = "^1.
|
|
28
|
+
mypy = "^1.9"
|
|
29
29
|
xdoctest = {extras = ["colors"], version = "^1.1.3"}
|
|
30
30
|
flake8-bandit = "~4.1.1"
|
|
31
31
|
flake8-bugbear = ">=21.9.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|