pgbelt 0.8.1__tar.gz → 0.8.3__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.8.1 → pgbelt-0.8.3}/PKG-INFO +3 -3
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/util/dump.py +5 -2
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/util/logs.py +17 -6
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/util/postgres.py +1 -1
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pyproject.toml +11 -11
- {pgbelt-0.8.1 → pgbelt-0.8.3}/LICENSE +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/README.md +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/__init__.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/__init__.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/convenience.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/helpers.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/login.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/preflight.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/schema.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/setup.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/status.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/sync.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/cmd/teardown.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/config/__init__.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/config/config.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/config/models.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/config/remote.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/main.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/util/__init__.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/util/asyncfuncs.py +0 -0
- {pgbelt-0.8.1 → pgbelt-0.8.3}/pgbelt/util/pglogical.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: pgbelt
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
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
|
|
@@ -15,7 +15,7 @@ Requires-Dist: aiofiles (>=0.8,<24.2)
|
|
|
15
15
|
Requires-Dist: asyncpg (>=0.27,<0.31)
|
|
16
16
|
Requires-Dist: pydantic (>=2.0,<3.0)
|
|
17
17
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
|
18
|
-
Requires-Dist: typer (>=0.9,<0.
|
|
18
|
+
Requires-Dist: typer (>=0.9,<0.16)
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
|
|
21
21
|
# Pgbelt
|
|
@@ -93,7 +93,7 @@ async def dump_source_tables(
|
|
|
93
93
|
[
|
|
94
94
|
"pg_dump",
|
|
95
95
|
"--data-only",
|
|
96
|
-
f
|
|
96
|
+
f'--table={config.schema_name}."{table}"',
|
|
97
97
|
"-Fc",
|
|
98
98
|
"-f",
|
|
99
99
|
table_file(config.db, config.dc, table),
|
|
@@ -401,13 +401,16 @@ async def create_target_indexes(
|
|
|
401
401
|
for c in create_index_statements.split(";"):
|
|
402
402
|
# Get the Index Name
|
|
403
403
|
regex_matches = search(
|
|
404
|
-
r"CREATE [UNIQUE ]*INDEX (?P<index>[a-zA-Z0-9._]+)+.*",
|
|
404
|
+
r"CREATE [UNIQUE ]*INDEX (?P<index>[a-zA-Z0-9._\"]+)+.*",
|
|
405
405
|
c,
|
|
406
406
|
)
|
|
407
407
|
if not regex_matches:
|
|
408
408
|
continue
|
|
409
409
|
index = regex_matches.groupdict()["index"]
|
|
410
410
|
|
|
411
|
+
# Sometimes the index name is quoted, so remove the quotes
|
|
412
|
+
index = index.replace('"', "")
|
|
413
|
+
|
|
411
414
|
# Create the index
|
|
412
415
|
# Note that the host DSN must have a statement timeout of 0.
|
|
413
416
|
# Example DSN: `host=server-hostname user=user dbname=db_name options='-c statement_timeout=3600000'`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from datetime import datetime
|
|
2
3
|
from os import getenv
|
|
3
4
|
from os import makedirs
|
|
4
5
|
|
|
@@ -8,7 +9,7 @@ FORMATTER = "{asctime} {name}:{levelname} {message}"
|
|
|
8
9
|
# if this module is ever imported we set up the root logger to log to stderr
|
|
9
10
|
root_level = int(getenv("LOG_LEVEL", logging.DEBUG))
|
|
10
11
|
root_handler = logging.StreamHandler()
|
|
11
|
-
formatter = logging.Formatter(fmt=FORMATTER, datefmt=
|
|
12
|
+
formatter = logging.Formatter(fmt=FORMATTER, datefmt="%Y-%m-%d %H:%M:%S", style="{")
|
|
12
13
|
root_handler.setFormatter(formatter)
|
|
13
14
|
root_handler.setLevel(root_level)
|
|
14
15
|
root_logger = logging.getLogger("dbup")
|
|
@@ -20,13 +21,21 @@ def log_file_dir(db: str, dc: str) -> str:
|
|
|
20
21
|
return f"logs/{db}/{dc}"
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
def log_file_path(db: str, dc: str) -> str:
|
|
24
|
-
|
|
24
|
+
def log_file_path(db: str, dc: str, kind: str) -> str:
|
|
25
|
+
timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
|
26
|
+
if kind:
|
|
27
|
+
return f"logs/{db}/{dc}/{timestamp}-{kind}.txt"
|
|
28
|
+
else:
|
|
29
|
+
return f"logs/{db}/{dc}/{timestamp}.txt"
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
def get_logger(db: str, dc: str, kind: str = "") -> logging.Logger:
|
|
28
33
|
# When we set up a logger for that db that emits to a file
|
|
29
|
-
logger =
|
|
34
|
+
logger = (
|
|
35
|
+
logging.getLogger(f"dbup.{db}.{dc}.{kind}")
|
|
36
|
+
if kind
|
|
37
|
+
else logging.getLogger(f"dbup.{db}.{dc}")
|
|
38
|
+
)
|
|
30
39
|
if not logger.handlers:
|
|
31
40
|
skip_file_handler = False
|
|
32
41
|
|
|
@@ -41,8 +50,10 @@ def get_logger(db: str, dc: str, kind: str = "") -> logging.Logger:
|
|
|
41
50
|
pass
|
|
42
51
|
|
|
43
52
|
if not skip_file_handler:
|
|
44
|
-
handler = logging.FileHandler(log_file_path(db, dc), mode="w")
|
|
45
|
-
handler.setFormatter(
|
|
53
|
+
handler = logging.FileHandler(log_file_path(db, dc, kind), mode="w")
|
|
54
|
+
handler.setFormatter(
|
|
55
|
+
logging.Formatter(FORMATTER, datefmt="%Y-%m-%d %H:%M:%S", style="{")
|
|
56
|
+
)
|
|
46
57
|
# always log everything to the file
|
|
47
58
|
logger.setLevel(logging.DEBUG)
|
|
48
59
|
logger.addHandler(handler)
|
|
@@ -264,7 +264,7 @@ async def table_empty(pool: Pool, table: str, schema: str, logger: Logger) -> bo
|
|
|
264
264
|
return true if the table is empty
|
|
265
265
|
"""
|
|
266
266
|
logger.info(f"Checking if table {table} is empty...")
|
|
267
|
-
result = await pool.fetch(f
|
|
267
|
+
result = await pool.fetch(f'SELECT * FROM {schema}."{table}" LIMIT 1;')
|
|
268
268
|
return len(result) == 0
|
|
269
269
|
|
|
270
270
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pgbelt"
|
|
3
|
-
version = "0.8.
|
|
3
|
+
version = "0.8.3"
|
|
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"
|
|
@@ -15,17 +15,17 @@ aiofiles = ">=0.8,<24.2"
|
|
|
15
15
|
asyncpg = ">=0.27,<0.31"
|
|
16
16
|
pydantic = ">=2.0,<3.0"
|
|
17
17
|
tabulate = "^0.9.0"
|
|
18
|
-
typer = ">=0.9,<0.
|
|
18
|
+
typer = ">=0.9,<0.16"
|
|
19
19
|
|
|
20
20
|
[tool.poetry.dev-dependencies]
|
|
21
|
-
black = "~
|
|
22
|
-
pre-commit = "~4.0
|
|
21
|
+
black = "~25.1.0"
|
|
22
|
+
pre-commit = "~4.1.0"
|
|
23
23
|
flake8 = "^7.1.1"
|
|
24
24
|
pytest-cov = "~6.0.0"
|
|
25
|
-
pytest = "^8.3.
|
|
25
|
+
pytest = "^8.3.4"
|
|
26
26
|
coverage = {extras = ["toml"], version = "^7.6"}
|
|
27
|
-
safety = "^3.2.
|
|
28
|
-
mypy = "^1.
|
|
27
|
+
safety = "^3.2.14"
|
|
28
|
+
mypy = "^1.14"
|
|
29
29
|
xdoctest = {extras = ["colors"], version = "^1.2.0"}
|
|
30
30
|
flake8-bandit = "~4.1.1"
|
|
31
31
|
flake8-bugbear = ">=21.9.2"
|
|
@@ -35,10 +35,10 @@ pep8-naming = "^0.14.1"
|
|
|
35
35
|
darglint = "^1.8.1"
|
|
36
36
|
reorder-python-imports = "^3.14.0"
|
|
37
37
|
pre-commit-hooks = "^5.0.0"
|
|
38
|
-
Pygments = "^2.
|
|
39
|
-
pyupgrade = "^3.19.
|
|
40
|
-
pylint = "^3.3.
|
|
41
|
-
pytest-asyncio = "~0.
|
|
38
|
+
Pygments = "^2.19.1"
|
|
39
|
+
pyupgrade = "^3.19.1"
|
|
40
|
+
pylint = "^3.3.4"
|
|
41
|
+
pytest-asyncio = "~0.25.3"
|
|
42
42
|
|
|
43
43
|
[build-system]
|
|
44
44
|
requires = ["poetry-core>=1.0.0", "setuptools"]
|
|
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
|
|
File without changes
|