pgsync 7.0.0__tar.gz → 7.0.1__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.
- {pgsync-7.0.0 → pgsync-7.0.1}/PKG-INFO +5 -5
- {pgsync-7.0.0 → pgsync-7.0.1}/README.md +1 -1
- {pgsync-7.0.0 → pgsync-7.0.1}/README.rst +1 -1
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/__init__.py +1 -1
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/settings.py +3 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/sync.py +20 -12
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync.egg-info/PKG-INFO +5 -5
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync.egg-info/requires.txt +3 -3
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_sync.py +3 -1
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_trigger.py +1 -1
- {pgsync-7.0.0 → pgsync-7.0.1}/AUTHORS.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/CONTRIBUTING.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/HISTORY.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/LICENSE +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/MANIFEST.in +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/bin/bootstrap +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/bin/parallel_sync +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/bin/pgsync +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/Makefile +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/authors.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/changelog.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/conf.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/contributing.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/history.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/index.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/installation.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/logo.png +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/make.bat +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/readme.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/docs/usage.rst +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/base.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/constants.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/exc.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/helper.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/node.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/plugin.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/querybuilder.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/redisqueue.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/search_client.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/singleton.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/transform.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/trigger.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/urls.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/utils.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync/view.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync.egg-info/SOURCES.txt +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync.egg-info/dependency_links.txt +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync.egg-info/not-zip-safe +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pgsync.egg-info/top_level.txt +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/pyproject.toml +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/setup.cfg +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/setup.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/__init__.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/conftest.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/fixtures/schema.json +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_base.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_constants.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_env_vars.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_helper.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_log_handlers.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_node.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_query_builder.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_redisqueue.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_search_client.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_settings.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_sync_nested_children.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_sync_root.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_sync_single_child_fk_on_child.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_sync_single_child_fk_on_parent.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_transform.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_unique_behaviour.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_urls.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_utils.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/test_view.py +0 -0
- {pgsync-7.0.0 → pgsync-7.0.1}/tests/testing_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pgsync
|
|
3
|
-
Version: 7.0.
|
|
3
|
+
Version: 7.0.1
|
|
4
4
|
Summary: Postgres/MySQL/MariaDB to Elasticsearch/OpenSearch sync
|
|
5
5
|
Home-page: https://github.com/toluaina/pgsync
|
|
6
6
|
Author: Tolu Aina
|
|
@@ -33,8 +33,8 @@ License-File: LICENSE
|
|
|
33
33
|
License-File: AUTHORS.rst
|
|
34
34
|
Requires-Dist: async-timeout==5.0.1
|
|
35
35
|
Requires-Dist: backports-datetime-fromisoformat==2.0.3
|
|
36
|
-
Requires-Dist: boto3==1.42.
|
|
37
|
-
Requires-Dist: botocore==1.42.
|
|
36
|
+
Requires-Dist: boto3==1.42.8
|
|
37
|
+
Requires-Dist: botocore==1.42.8
|
|
38
38
|
Requires-Dist: certifi==2025.11.12
|
|
39
39
|
Requires-Dist: charset-normalizer==3.4.4
|
|
40
40
|
Requires-Dist: click==8.1.8
|
|
@@ -60,7 +60,7 @@ Requires-Dist: requests==2.32.5
|
|
|
60
60
|
Requires-Dist: requests-aws4auth==1.3.1
|
|
61
61
|
Requires-Dist: s3transfer==0.16.0
|
|
62
62
|
Requires-Dist: six==1.17.0
|
|
63
|
-
Requires-Dist: sqlalchemy==2.0.
|
|
63
|
+
Requires-Dist: sqlalchemy==2.0.45
|
|
64
64
|
Requires-Dist: sqlparse==0.5.4
|
|
65
65
|
Requires-Dist: typing-extensions==4.15.0
|
|
66
66
|
Requires-Dist: urllib3==1.26.20
|
|
@@ -92,7 +92,7 @@ expose structured denormalized documents in [Elasticsearch](https://www.elastic.
|
|
|
92
92
|
|
|
93
93
|
- [Python](https://www.python.org) 3.9+
|
|
94
94
|
- [Postgres](https://www.postgresql.org) 9.6+ or [MySQL](https://www.mysql.com/) 8.0.0+ or [MariaDB](https://mariadb.org/) 12.0.0+
|
|
95
|
-
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+
|
|
95
|
+
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+ (Optional in wal mode)
|
|
96
96
|
- [Elasticsearch](https://www.elastic.co/products/elastic-stack) 6.3.1+ or [OpenSearch](https://opensearch.org/) 1.3.7+
|
|
97
97
|
- [SQLAlchemy](https://www.sqlalchemy.org) 1.3.4+
|
|
98
98
|
|
|
@@ -241,7 +241,7 @@ Key features of PGSync are:
|
|
|
241
241
|
|
|
242
242
|
- [Python](https://www.python.org) 3.9+
|
|
243
243
|
- [Postgres](https://www.postgresql.org) 9.6+ or [MySQL](https://www.mysql.com/) 5.7.22+ or [MariaDB](https://mariadb.org/) 10.5.0+
|
|
244
|
-
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+
|
|
244
|
+
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+ (Optional in wal mode)
|
|
245
245
|
- [Elasticsearch](https://www.elastic.co/products/elastic-stack) 6.3.1+ or [OpenSearch](https://opensearch.org/) 1.3.7+
|
|
246
246
|
- [SQLAlchemy](https://www.sqlalchemy.org) 1.3.4+
|
|
247
247
|
|
|
@@ -10,7 +10,7 @@ expose structured denormalized documents in [Elasticsearch](https://www.elastic.
|
|
|
10
10
|
|
|
11
11
|
- [Python](https://www.python.org) 3.9+
|
|
12
12
|
- [Postgres](https://www.postgresql.org) 9.6+ or [MySQL](https://www.mysql.com/) 8.0.0+ or [MariaDB](https://mariadb.org/) 12.0.0+
|
|
13
|
-
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+
|
|
13
|
+
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+ (Optional in wal mode)
|
|
14
14
|
- [Elasticsearch](https://www.elastic.co/products/elastic-stack) 6.3.1+ or [OpenSearch](https://opensearch.org/) 1.3.7+
|
|
15
15
|
- [SQLAlchemy](https://www.sqlalchemy.org) 1.3.4+
|
|
16
16
|
|
|
@@ -52,6 +52,9 @@ STREAM_RESULTS = env.bool("STREAM_RESULTS", default=True)
|
|
|
52
52
|
POLL_INTERVAL = env.float("POLL_INTERVAL", default=0.1)
|
|
53
53
|
FORMAT_WITH_COMMAS = env.bool("FORMAT_WITH_COMMAS", default=True)
|
|
54
54
|
|
|
55
|
+
POLLING = env.bool("POLLING", default=False)
|
|
56
|
+
WAL = env.bool("WAL", default=False)
|
|
57
|
+
|
|
55
58
|
# SQLAlchemy Settings:
|
|
56
59
|
# Use NullPool (no connection pooling) - useful for testing or when you want to close connections immediately
|
|
57
60
|
SQLALCHEMY_USE_NULLPOOL = env.bool("SQLALCHEMY_USE_NULLPOOL", default=False)
|
|
@@ -126,8 +126,9 @@ class Sync(Base, metaclass=Singleton):
|
|
|
126
126
|
self.tree: Tree = Tree(
|
|
127
127
|
self.models, nodes=self.nodes, database=doc["database"]
|
|
128
128
|
)
|
|
129
|
+
|
|
129
130
|
if bootstrap:
|
|
130
|
-
self.setup(polling=polling)
|
|
131
|
+
self.setup(polling=polling, wal=wal)
|
|
131
132
|
|
|
132
133
|
if validate:
|
|
133
134
|
self.validate(repl_slots=repl_slots, polling=polling)
|
|
@@ -322,7 +323,9 @@ class Sync(Base, metaclass=Singleton):
|
|
|
322
323
|
routing=self.routing,
|
|
323
324
|
)
|
|
324
325
|
|
|
325
|
-
def setup(
|
|
326
|
+
def setup(
|
|
327
|
+
self, no_create: bool = False, polling: bool = False, wal: bool = False
|
|
328
|
+
) -> None:
|
|
326
329
|
"""Create the database triggers and replication slot.
|
|
327
330
|
Generally bootstrap should not require Redis as it is optional in certain cases.
|
|
328
331
|
"""
|
|
@@ -340,9 +343,9 @@ class Sync(Base, metaclass=Singleton):
|
|
|
340
343
|
):
|
|
341
344
|
if if_not_exists:
|
|
342
345
|
|
|
343
|
-
self.teardown(drop_view=False)
|
|
346
|
+
self.teardown(drop_view=False, polling=polling, wal=wal)
|
|
344
347
|
|
|
345
|
-
if not polling:
|
|
348
|
+
if not polling and not wal:
|
|
346
349
|
for schema in self.schemas:
|
|
347
350
|
if schema not in self.tree.schemas:
|
|
348
351
|
logger.warning(
|
|
@@ -428,6 +431,7 @@ class Sync(Base, metaclass=Singleton):
|
|
|
428
431
|
self,
|
|
429
432
|
drop_view: bool = True,
|
|
430
433
|
polling: bool = False,
|
|
434
|
+
wal: bool = False,
|
|
431
435
|
) -> None:
|
|
432
436
|
"""Drop the database triggers and replication slot."""
|
|
433
437
|
if self.is_mysql_compat:
|
|
@@ -447,14 +451,17 @@ class Sync(Base, metaclass=Singleton):
|
|
|
447
451
|
f"Checkpoint file not found: {self.checkpoint_file}"
|
|
448
452
|
)
|
|
449
453
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
if not wal and not settings.REDIS_CHECKPOINT:
|
|
455
|
+
try:
|
|
456
|
+
if self.redis is None:
|
|
457
|
+
raise RuntimeError("Redis is not configured.")
|
|
458
|
+
self.redis.delete()
|
|
459
|
+
except Exception as e:
|
|
460
|
+
logger.warning(
|
|
461
|
+
f"Could not clear Redis checkpoint queue: {e}"
|
|
462
|
+
)
|
|
456
463
|
|
|
457
|
-
if not polling:
|
|
464
|
+
if not polling and not wal:
|
|
458
465
|
for schema in self.schemas:
|
|
459
466
|
if schema not in self.tree.schemas:
|
|
460
467
|
logger.warning(
|
|
@@ -2134,6 +2141,7 @@ class Sync(Base, metaclass=Singleton):
|
|
|
2134
2141
|
@click.option(
|
|
2135
2142
|
"--polling",
|
|
2136
2143
|
is_flag=True,
|
|
2144
|
+
default=settings.POLLING,
|
|
2137
2145
|
help="Polling mode (Incompatible with -d)",
|
|
2138
2146
|
cls=MutuallyExclusiveOption,
|
|
2139
2147
|
mutually_exclusive=["daemon", "wal"],
|
|
@@ -2142,7 +2150,7 @@ class Sync(Base, metaclass=Singleton):
|
|
|
2142
2150
|
"--wal",
|
|
2143
2151
|
"-w",
|
|
2144
2152
|
is_flag=True,
|
|
2145
|
-
default=
|
|
2153
|
+
default=settings.WAL,
|
|
2146
2154
|
help="Use WAL for replication",
|
|
2147
2155
|
cls=MutuallyExclusiveOption,
|
|
2148
2156
|
mutually_exclusive=[
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pgsync
|
|
3
|
-
Version: 7.0.
|
|
3
|
+
Version: 7.0.1
|
|
4
4
|
Summary: Postgres/MySQL/MariaDB to Elasticsearch/OpenSearch sync
|
|
5
5
|
Home-page: https://github.com/toluaina/pgsync
|
|
6
6
|
Author: Tolu Aina
|
|
@@ -33,8 +33,8 @@ License-File: LICENSE
|
|
|
33
33
|
License-File: AUTHORS.rst
|
|
34
34
|
Requires-Dist: async-timeout==5.0.1
|
|
35
35
|
Requires-Dist: backports-datetime-fromisoformat==2.0.3
|
|
36
|
-
Requires-Dist: boto3==1.42.
|
|
37
|
-
Requires-Dist: botocore==1.42.
|
|
36
|
+
Requires-Dist: boto3==1.42.8
|
|
37
|
+
Requires-Dist: botocore==1.42.8
|
|
38
38
|
Requires-Dist: certifi==2025.11.12
|
|
39
39
|
Requires-Dist: charset-normalizer==3.4.4
|
|
40
40
|
Requires-Dist: click==8.1.8
|
|
@@ -60,7 +60,7 @@ Requires-Dist: requests==2.32.5
|
|
|
60
60
|
Requires-Dist: requests-aws4auth==1.3.1
|
|
61
61
|
Requires-Dist: s3transfer==0.16.0
|
|
62
62
|
Requires-Dist: six==1.17.0
|
|
63
|
-
Requires-Dist: sqlalchemy==2.0.
|
|
63
|
+
Requires-Dist: sqlalchemy==2.0.45
|
|
64
64
|
Requires-Dist: sqlparse==0.5.4
|
|
65
65
|
Requires-Dist: typing-extensions==4.15.0
|
|
66
66
|
Requires-Dist: urllib3==1.26.20
|
|
@@ -92,7 +92,7 @@ expose structured denormalized documents in [Elasticsearch](https://www.elastic.
|
|
|
92
92
|
|
|
93
93
|
- [Python](https://www.python.org) 3.9+
|
|
94
94
|
- [Postgres](https://www.postgresql.org) 9.6+ or [MySQL](https://www.mysql.com/) 8.0.0+ or [MariaDB](https://mariadb.org/) 12.0.0+
|
|
95
|
-
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+
|
|
95
|
+
- [Redis](https://redis.io) 3.1.0+ or [Valkey](https://valkey.io) 7.2.0+ (Optional in wal mode)
|
|
96
96
|
- [Elasticsearch](https://www.elastic.co/products/elastic-stack) 6.3.1+ or [OpenSearch](https://opensearch.org/) 1.3.7+
|
|
97
97
|
- [SQLAlchemy](https://www.sqlalchemy.org) 1.3.4+
|
|
98
98
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
async-timeout==5.0.1
|
|
2
2
|
backports-datetime-fromisoformat==2.0.3
|
|
3
|
-
boto3==1.42.
|
|
4
|
-
botocore==1.42.
|
|
3
|
+
boto3==1.42.8
|
|
4
|
+
botocore==1.42.8
|
|
5
5
|
certifi==2025.11.12
|
|
6
6
|
charset-normalizer==3.4.4
|
|
7
7
|
click==8.1.8
|
|
@@ -27,7 +27,7 @@ requests==2.32.5
|
|
|
27
27
|
requests-aws4auth==1.3.1
|
|
28
28
|
s3transfer==0.16.0
|
|
29
29
|
six==1.17.0
|
|
30
|
-
sqlalchemy==2.0.
|
|
30
|
+
sqlalchemy==2.0.45
|
|
31
31
|
sqlparse==0.5.4
|
|
32
32
|
typing-extensions==4.15.0
|
|
33
33
|
urllib3==1.26.20
|
|
@@ -937,7 +937,9 @@ class TestSync(object):
|
|
|
937
937
|
},
|
|
938
938
|
)
|
|
939
939
|
mock_create_function.assert_called_once_with("public")
|
|
940
|
-
mock_teardown.assert_called_once_with(
|
|
940
|
+
mock_teardown.assert_called_once_with(
|
|
941
|
+
drop_view=False, polling=False, wal=False
|
|
942
|
+
)
|
|
941
943
|
|
|
942
944
|
@patch("pgsync.redisqueue.RedisQueue.delete")
|
|
943
945
|
def test_teardown(self, mock_redis_delete, sync):
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|