plexus-python-common 1.0.46__tar.gz → 1.0.48__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.
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/PKG-INFO +1 -1
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/bagutils.py +33 -34
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/config.py +5 -3
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/jsonutils.py +1 -1
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/ormutils.py +9 -9
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/s3utils.py +31 -26
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/tagutils.py +10 -10
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus_python_common.egg-info/PKG-INFO +1 -1
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus_python_common.egg-info/SOURCES.txt +22 -19
- plexus_python_common-1.0.48/test/plexus_tests/__init__.py +0 -0
- plexus_python_common-1.0.48/test/plexus_tests/common/__init__.py +0 -0
- plexus_python_common-1.0.48/test/plexus_tests/common/carto/__init__.py +0 -0
- plexus_python_common-1.0.48/test/plexus_tests/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/jsonutils_test.py +2 -3
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/ormutils_test.py +83 -0
- plexus_python_common-1.0.46/test/plexus_tests/common/utils/shutils_test.py → plexus_python_common-1.0.48/test/plexus_tests/common/utils/pathutils_test.py +9 -14
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/s3utils_test.py +69 -59
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/tagutils_test.py +1 -2
- plexus_python_common-1.0.48/test/testenv.py +15 -0
- plexus_python_common-1.0.46/test/plexus_test.py +0 -13
- plexus_python_common-1.0.46/test/plexus_tests/__init__.py +0 -15
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/.editorconfig +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/.github/workflows/pr.yml +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/.github/workflows/push.yml +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/.gitignore +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/MANIFEST.in +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/README.md +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/VERSION +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/pyproject.toml +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/0-dummy +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/1-dummy +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/2-dummy +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.0.0.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.0.0.vol-0.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.1.1.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.1.1.vol-1.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.2.2.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.2.2.vol-2.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.csv.part0 +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.csv.part1 +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.csv.part2 +0 -0
- {plexus_python_common-1.0.46/resources/unittest/shutils → plexus_python_common-1.0.48/resources/unittest/pathutils}/dummy.txt +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/file.bar +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/file.baz +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils/dir.foo/file.foo +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils_archive/archive.compressed.zip +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/resources/unittest/s3utils_archive/archive.uncompressed.zip +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/setup.cfg +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/setup.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/__init__.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/carto/OSMFile.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/carto/OSMNode.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/carto/OSMTags.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/carto/OSMWay.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/pose.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/proj.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/resources/__init__.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/resources/tags/__init__.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/resources/tags/universal.tagset.yaml +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/apiutils.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/datautils.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/dockerutils.py +0 -0
- /plexus_python_common-1.0.46/src/plexus/common/utils/shutils.py → /plexus_python_common-1.0.48/src/plexus/common/utils/pathutils.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/sqlutils.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/strutils.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/testutils.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus_python_common.egg-info/requires.txt +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus_python_common.egg-info/top_level.txt +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/pose_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/proj_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/datautils_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/dockerutils_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/strutils_test.py +0 -0
- {plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/test/plexus_tests/common/utils/testutils_test.py +0 -0
{plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/bagutils.py
RENAMED
|
@@ -5,6 +5,7 @@ from typing import Literal
|
|
|
5
5
|
|
|
6
6
|
import sqlalchemy as sa
|
|
7
7
|
import sqlalchemy.orm as sa_orm
|
|
8
|
+
from iker.common.utils.pathutils import make_path
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
10
11
|
"SerializationFormat",
|
|
@@ -77,12 +78,20 @@ class BagMessage(BagBase):
|
|
|
77
78
|
|
|
78
79
|
|
|
79
80
|
class BagReader(AbstractContextManager):
|
|
80
|
-
def __init__(self, db_dir: str, db_file: str = default_bag_db_file):
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
def __init__(self, db_dir: str | os.PathLike[str], db_file: str | os.PathLike[str] = default_bag_db_file):
|
|
82
|
+
"""
|
|
83
|
+
Creates a BagReader instance to read messages from a ROS2 bag file.
|
|
84
|
+
|
|
85
|
+
:param db_dir: directory containing the SQLite DB file.
|
|
86
|
+
:param db_file: name of the SQLite DB file.
|
|
87
|
+
:return: BagReader instance.
|
|
88
|
+
"""
|
|
89
|
+
self.db_dir = make_path(db_dir)
|
|
90
|
+
self.db_path = self.db_dir / db_file
|
|
91
|
+
if not self.db_path.exists():
|
|
92
|
+
raise FileNotFoundError(f"could not find SQLite DB at '{str(self.db_path)}'")
|
|
93
|
+
|
|
94
|
+
self.engine = sa.create_engine(f"sqlite:///{str(self.db_path.absolute())}")
|
|
86
95
|
self.session = sa_orm.Session(self.engine)
|
|
87
96
|
self.topic_map = None
|
|
88
97
|
|
|
@@ -121,12 +130,22 @@ class BagReader(AbstractContextManager):
|
|
|
121
130
|
|
|
122
131
|
|
|
123
132
|
class BagWriter(AbstractContextManager):
|
|
124
|
-
def __init__(self, db_dir: str, db_file: str = default_bag_db_file):
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
def __init__(self, db_dir: str | os.PathLike[str], db_file: str | os.PathLike[str] = default_bag_db_file):
|
|
134
|
+
"""
|
|
135
|
+
Creates a BagWriter instance to write messages to a ROS2 bag file.
|
|
136
|
+
|
|
137
|
+
:param db_dir: directory to store the SQLite DB file.
|
|
138
|
+
:param db_file: name of the SQLite DB file.
|
|
139
|
+
:return: BagWriter instance.
|
|
140
|
+
"""
|
|
141
|
+
self.db_dir = make_path(db_dir)
|
|
142
|
+
if not self.db_dir.exists():
|
|
143
|
+
self.db_dir.mkdir(parents=True, exist_ok=True)
|
|
144
|
+
self.db_path = self.db_dir / db_file
|
|
145
|
+
if self.db_path.exists():
|
|
146
|
+
self.db_path.unlink()
|
|
147
|
+
|
|
148
|
+
self.engine = sa.create_engine(f"sqlite:///{str(self.db_path.absolute())}")
|
|
130
149
|
self.session = sa_orm.Session(self.engine)
|
|
131
150
|
self.topic_map = {}
|
|
132
151
|
|
|
@@ -191,25 +210,5 @@ class BagWriter(AbstractContextManager):
|
|
|
191
210
|
return db_message
|
|
192
211
|
|
|
193
212
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
Creates a BagReader instance to read messages from a ROS2 bag file.
|
|
197
|
-
|
|
198
|
-
:param db_dir: directory containing the SQLite DB file.
|
|
199
|
-
:param db_file: name of the SQLite DB file.
|
|
200
|
-
:return: BagReader instance.
|
|
201
|
-
"""
|
|
202
|
-
return BagReader(db_dir, db_file)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def bag_writer(db_dir: str, db_file: str = default_bag_db_file) -> BagWriter:
|
|
206
|
-
"""
|
|
207
|
-
Creates a BagWriter instance to write messages to a ROS2 bag file.
|
|
208
|
-
|
|
209
|
-
:param db_dir: directory to store the SQLite DB file.
|
|
210
|
-
:param db_file: name of the SQLite DB file.
|
|
211
|
-
:return: BagWriter instance.
|
|
212
|
-
"""
|
|
213
|
-
if not os.path.exists(db_dir):
|
|
214
|
-
os.makedirs(db_dir, exist_ok=True)
|
|
215
|
-
return BagWriter(db_dir, db_file)
|
|
213
|
+
bag_reader = BagReader
|
|
214
|
+
bag_writer = BagWriter
|
{plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/config.py
RENAMED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
1
3
|
from iker.common.utils import logger
|
|
2
4
|
from iker.common.utils.config import Config
|
|
3
5
|
from iker.common.utils.funcutils import memorized
|
|
4
|
-
from iker.common.utils.
|
|
6
|
+
from iker.common.utils.pathutils import make_path
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
@memorized()
|
|
8
|
-
def config(config_path: str = "") -> Config:
|
|
10
|
+
def config(config_path: str | os.PathLike[str] = "") -> Config:
|
|
9
11
|
default_items: list[tuple[str, str, str]] = [
|
|
10
12
|
("plexus", "logging.level", "INFO"),
|
|
11
13
|
("plexus", "logging.format", "%(asctime)s [%(levelname)s] %(name)s: %(message)s"),
|
|
12
14
|
]
|
|
13
15
|
|
|
14
|
-
instance = Config(config_path or
|
|
16
|
+
instance = Config(config_path or make_path("~/.plexus.cfg", expand=True, normalize=True, absolute=True))
|
|
15
17
|
instance.restore()
|
|
16
18
|
instance.update(default_items, overwrite=False)
|
|
17
19
|
|
{plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/jsonutils.py
RENAMED
|
@@ -9,7 +9,7 @@ from iker.common.utils.iterutils import batched
|
|
|
9
9
|
from iker.common.utils.jsonutils import JsonType, JsonValueCompatible
|
|
10
10
|
from iker.common.utils.jsonutils import json_reformat
|
|
11
11
|
|
|
12
|
-
from plexus.common.utils.
|
|
12
|
+
from plexus.common.utils.pathutils import collect_volumed_filenames, populate_volumed_filenames
|
|
13
13
|
|
|
14
14
|
__all__ = [
|
|
15
15
|
"json_datetime_decoder",
|
{plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/ormutils.py
RENAMED
|
@@ -1146,7 +1146,7 @@ def db_read_active_snapshot_model_of_record[SnapshotModelT: SnapshotModelMixin](
|
|
|
1146
1146
|
) -> SnapshotModelT:
|
|
1147
1147
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1148
1148
|
if db_instance is None:
|
|
1149
|
-
raise sa_exc.NoResultFound(f"
|
|
1149
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1150
1150
|
|
|
1151
1151
|
return db_instance
|
|
1152
1152
|
|
|
@@ -1218,7 +1218,7 @@ def db_update_snapshot_model[SnapshotModelT: SnapshotModelMixin](
|
|
|
1218
1218
|
) -> SnapshotModelT:
|
|
1219
1219
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1220
1220
|
if db_instance is None:
|
|
1221
|
-
raise sa_exc.NoResultFound(f"
|
|
1221
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1222
1222
|
|
|
1223
1223
|
db_instance.expired_at = updated_at
|
|
1224
1224
|
db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1247,7 +1247,7 @@ def db_expire_snapshot_model[SnapshotModelT: SnapshotModelMixin](
|
|
|
1247
1247
|
.one_or_none()
|
|
1248
1248
|
)
|
|
1249
1249
|
if db_instance is None:
|
|
1250
|
-
raise sa_exc.NoResultFound(f"
|
|
1250
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1251
1251
|
|
|
1252
1252
|
db_instance.expired_at = updated_at
|
|
1253
1253
|
db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1275,7 +1275,7 @@ def db_activate_snapshot_model[SnapshotModelT: SnapshotModelMixin](
|
|
|
1275
1275
|
.first()
|
|
1276
1276
|
)
|
|
1277
1277
|
if db_instance is None:
|
|
1278
|
-
raise sa_exc.NoResultFound(f"
|
|
1278
|
+
raise sa_exc.NoResultFound(f"expired '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1279
1279
|
|
|
1280
1280
|
db_new_instance = clone_snapshot_model_instance(model, db_instance)
|
|
1281
1281
|
db_new_instance.record_sqn = record_sqn
|
|
@@ -1371,7 +1371,7 @@ def db_read_active_revision_model_of_record[RevisionModelT: RevisionModelMixin](
|
|
|
1371
1371
|
) -> RevisionModelT:
|
|
1372
1372
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1373
1373
|
if db_instance is None:
|
|
1374
|
-
raise sa_exc.NoResultFound(f"
|
|
1374
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1375
1375
|
|
|
1376
1376
|
return db_instance
|
|
1377
1377
|
|
|
@@ -1443,7 +1443,7 @@ def db_update_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1443
1443
|
) -> RevisionModelT:
|
|
1444
1444
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1445
1445
|
if db_instance is None:
|
|
1446
|
-
raise sa_exc.NoResultFound(f"
|
|
1446
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1447
1447
|
|
|
1448
1448
|
db_instance.expired_at = updated_at
|
|
1449
1449
|
db_instance = clone_revision_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1474,7 +1474,7 @@ def db_expire_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1474
1474
|
.one_or_none()
|
|
1475
1475
|
)
|
|
1476
1476
|
if db_instance is None:
|
|
1477
|
-
raise sa_exc.NoResultFound(f"
|
|
1477
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1478
1478
|
|
|
1479
1479
|
db_instance.expired_at = updated_at
|
|
1480
1480
|
db_instance = clone_revision_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1492,7 +1492,7 @@ def db_activate_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1492
1492
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1493
1493
|
if db_instance is not None:
|
|
1494
1494
|
raise sa_exc.MultipleResultsFound(
|
|
1495
|
-
f"
|
|
1495
|
+
f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' already exists")
|
|
1496
1496
|
|
|
1497
1497
|
db_instance = (
|
|
1498
1498
|
db
|
|
@@ -1502,7 +1502,7 @@ def db_activate_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1502
1502
|
.first()
|
|
1503
1503
|
)
|
|
1504
1504
|
if db_instance is None:
|
|
1505
|
-
raise sa_exc.NoResultFound(f"
|
|
1505
|
+
raise sa_exc.NoResultFound(f"expired '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1506
1506
|
|
|
1507
1507
|
db_new_instance = clone_revision_model_instance(model, db_instance)
|
|
1508
1508
|
db_new_instance.record_sqn = record_sqn
|
{plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/s3utils.py
RENAMED
|
@@ -6,7 +6,7 @@ import functools
|
|
|
6
6
|
import io
|
|
7
7
|
import mimetypes
|
|
8
8
|
import os
|
|
9
|
-
import
|
|
9
|
+
import pathlib
|
|
10
10
|
import shutil
|
|
11
11
|
import tempfile
|
|
12
12
|
import typing
|
|
@@ -20,7 +20,7 @@ import fsspec
|
|
|
20
20
|
import fsspec.utils
|
|
21
21
|
from iker.common.utils.iterutils import chunk_between, head, last
|
|
22
22
|
from iker.common.utils.jsonutils import JsonObject
|
|
23
|
-
from iker.common.utils.
|
|
23
|
+
from iker.common.utils.pathutils import glob_match, make_path, path_depth, scan_files
|
|
24
24
|
from iker.common.utils.strutils import is_empty, trim_to_none
|
|
25
25
|
from mypy_boto3_s3 import S3Client
|
|
26
26
|
from rich.progress import BarColumn, DownloadColumn, Progress, TextColumn, TransferSpeedColumn
|
|
@@ -30,7 +30,7 @@ __all__ = [
|
|
|
30
30
|
"s3_make_client",
|
|
31
31
|
"s3_head_object",
|
|
32
32
|
"s3_list_objects",
|
|
33
|
-
"
|
|
33
|
+
"s3_list_files",
|
|
34
34
|
"s3_cp_download",
|
|
35
35
|
"s3_cp_upload",
|
|
36
36
|
"s3_sync_download",
|
|
@@ -40,7 +40,7 @@ __all__ = [
|
|
|
40
40
|
"s3_make_progressed_client",
|
|
41
41
|
"ArchiveMemberChunk",
|
|
42
42
|
"s3_archive_member_tree",
|
|
43
|
-
"
|
|
43
|
+
"s3_archive_list_files",
|
|
44
44
|
"s3_archive_open_member",
|
|
45
45
|
"s3_archive_use_ranged_requests",
|
|
46
46
|
"s3_archive_use_chunked_reads",
|
|
@@ -147,7 +147,7 @@ def s3_list_objects(
|
|
|
147
147
|
continuation_token = response.get("NextContinuationToken")
|
|
148
148
|
|
|
149
149
|
|
|
150
|
-
def
|
|
150
|
+
def s3_list_files(
|
|
151
151
|
client: S3Client,
|
|
152
152
|
bucket: str,
|
|
153
153
|
prefix: str,
|
|
@@ -173,9 +173,10 @@ def s3_listfile(
|
|
|
173
173
|
prefix = prefix + "/"
|
|
174
174
|
|
|
175
175
|
def filter_object_meta(object_meta: S3ObjectMeta) -> bool:
|
|
176
|
-
|
|
176
|
+
object_path = make_path(object_meta.key)
|
|
177
|
+
if 0 < depth <= path_depth(prefix, object_path.parent):
|
|
177
178
|
return False
|
|
178
|
-
if len(glob_match([
|
|
179
|
+
if len(glob_match([object_path.name], include_patterns, exclude_patterns)) == 0:
|
|
179
180
|
return False
|
|
180
181
|
return True
|
|
181
182
|
|
|
@@ -238,16 +239,18 @@ def s3_sync_download(
|
|
|
238
239
|
if not prefix.endswith("/"):
|
|
239
240
|
prefix = prefix + "/"
|
|
240
241
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
242
|
+
dir_path = make_path(dir_path)
|
|
243
|
+
|
|
244
|
+
objects = s3_list_files(client,
|
|
245
|
+
bucket,
|
|
246
|
+
prefix,
|
|
247
|
+
include_patterns=include_patterns,
|
|
248
|
+
exclude_patterns=exclude_patterns,
|
|
249
|
+
depth=depth)
|
|
247
250
|
|
|
248
251
|
def download_file(key: str):
|
|
249
|
-
file_path =
|
|
250
|
-
|
|
252
|
+
file_path = dir_path / key[len(prefix):]
|
|
253
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
251
254
|
s3_cp_download(client, bucket, key, file_path)
|
|
252
255
|
|
|
253
256
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
@@ -293,13 +296,15 @@ def s3_sync_upload(
|
|
|
293
296
|
if not prefix.endswith("/"):
|
|
294
297
|
prefix = prefix + "/"
|
|
295
298
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
299
|
+
dir_path = make_path(dir_path)
|
|
300
|
+
|
|
301
|
+
file_paths = scan_files(dir_path,
|
|
302
|
+
include_patterns=include_patterns,
|
|
303
|
+
exclude_patterns=exclude_patterns,
|
|
304
|
+
depth=depth)
|
|
300
305
|
|
|
301
|
-
def upload_file(file_path:
|
|
302
|
-
s3_cp_upload(client, file_path, bucket, prefix +
|
|
306
|
+
def upload_file(file_path: pathlib.Path):
|
|
307
|
+
s3_cp_upload(client, file_path, bucket, prefix + str(file_path.relative_to(dir_path)))
|
|
303
308
|
|
|
304
309
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
305
310
|
futures = [executor.submit(upload_file, file_path) for file_path in file_paths]
|
|
@@ -415,7 +420,7 @@ class S3ClientProgressProxy(object):
|
|
|
415
420
|
Callback=None,
|
|
416
421
|
Config=None,
|
|
417
422
|
):
|
|
418
|
-
bytes_total =
|
|
423
|
+
bytes_total = make_path(Filename).stat().st_size
|
|
419
424
|
with (
|
|
420
425
|
contextlib.nullcontext(Callback) if Callback is not None
|
|
421
426
|
else self.make_transfer_callback(Key, bytes_total, "upload")
|
|
@@ -585,7 +590,7 @@ def s3_archive_member_tree(
|
|
|
585
590
|
return root_member_tree
|
|
586
591
|
|
|
587
592
|
|
|
588
|
-
def
|
|
593
|
+
def s3_archive_list_files(
|
|
589
594
|
client: S3Client,
|
|
590
595
|
bucket: str,
|
|
591
596
|
key: str,
|
|
@@ -597,7 +602,7 @@ def s3_archive_listfile(
|
|
|
597
602
|
under that directory will be included in the results.
|
|
598
603
|
|
|
599
604
|
Example usage:
|
|
600
|
-
>>> archive_size, member_zip_infos, missed_members =
|
|
605
|
+
>>> archive_size, member_zip_infos, missed_members = s3_archive_list_files(client, bucket, key, members=["file1.txt", "dir1/"])
|
|
601
606
|
>>> for info in member_zip_infos:
|
|
602
607
|
... print(info.filename, info.file_size)
|
|
603
608
|
>>> if missed_members:
|
|
@@ -836,9 +841,9 @@ def s3_archive_open_members(
|
|
|
836
841
|
|
|
837
842
|
s3_options = s3_options_from_s3_client(client)
|
|
838
843
|
|
|
839
|
-
archive_size, member_zip_infos, missed_members =
|
|
844
|
+
archive_size, member_zip_infos, missed_members = s3_archive_list_files(client, bucket, key, members)
|
|
840
845
|
if missed_members:
|
|
841
|
-
raise FileNotFoundError(f"
|
|
846
|
+
raise FileNotFoundError(f"archive members not found: {', '.join(missed_members)}")
|
|
842
847
|
|
|
843
848
|
if callable(use_ranged_requests):
|
|
844
849
|
use_ranged_requests = use_ranged_requests(archive_size, member_zip_infos)
|
{plexus_python_common-1.0.46 → plexus_python_common-1.0.48}/src/plexus/common/utils/tagutils.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import datetime
|
|
3
|
-
import os
|
|
3
|
+
import os
|
|
4
|
+
import pathlib
|
|
4
5
|
import textwrap
|
|
5
6
|
import typing
|
|
6
7
|
from collections.abc import Generator, Mapping, Sequence
|
|
@@ -324,18 +325,17 @@ def render_tagset_markdown_readme(tagset: Tagset) -> str:
|
|
|
324
325
|
|
|
325
326
|
|
|
326
327
|
@singleton
|
|
327
|
-
def tag_cache_file_path() ->
|
|
328
|
-
return
|
|
328
|
+
def tag_cache_file_path() -> pathlib.Path:
|
|
329
|
+
return pathlib.Path.home() / ".local" / "plus" / "datahub" / "tag_cache" / f"{randomizer().random_alphanumeric(7)}.db"
|
|
329
330
|
|
|
330
331
|
|
|
331
332
|
class TagCache(object):
|
|
332
|
-
def __init__(self, *, file_path: str | None = None, fail_if_exists: bool = False):
|
|
333
|
-
self.file_path = file_path or tag_cache_file_path()
|
|
334
|
-
if fail_if_exists and
|
|
335
|
-
raise FileExistsError(f"tag cache file '{self.file_path}' already exists")
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
self.conn_maker = ConnectionMaker.from_url(f"sqlite:///{self.file_path}",
|
|
333
|
+
def __init__(self, *, file_path: str | os.PathLike[str] | None = None, fail_if_exists: bool = False):
|
|
334
|
+
self.file_path = pathlib.Path(file_path or tag_cache_file_path())
|
|
335
|
+
if fail_if_exists and self.file_path.exists():
|
|
336
|
+
raise FileExistsError(f"tag cache file '{str(self.file_path)}' already exists")
|
|
337
|
+
self.file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
338
|
+
self.conn_maker = ConnectionMaker.from_url(f"sqlite:///{str(self.file_path.absolute())}",
|
|
339
339
|
engine_opts=dict(connect_args={"check_same_thread": False}))
|
|
340
340
|
BaseModel.metadata.create_all(self.conn_maker.engine)
|
|
341
341
|
|
|
@@ -10,6 +10,22 @@ setup.py
|
|
|
10
10
|
resources/unittest/jsonutils/dummy.0.jsonl
|
|
11
11
|
resources/unittest/jsonutils/dummy.1.jsonl
|
|
12
12
|
resources/unittest/jsonutils/dummy.2.jsonl
|
|
13
|
+
resources/unittest/pathutils/0-dummy
|
|
14
|
+
resources/unittest/pathutils/1-dummy
|
|
15
|
+
resources/unittest/pathutils/2-dummy
|
|
16
|
+
resources/unittest/pathutils/dummy.0.0.jsonl
|
|
17
|
+
resources/unittest/pathutils/dummy.0.0.vol-0.jsonl
|
|
18
|
+
resources/unittest/pathutils/dummy.0.jsonl
|
|
19
|
+
resources/unittest/pathutils/dummy.1.1.jsonl
|
|
20
|
+
resources/unittest/pathutils/dummy.1.1.vol-1.jsonl
|
|
21
|
+
resources/unittest/pathutils/dummy.1.jsonl
|
|
22
|
+
resources/unittest/pathutils/dummy.2.2.jsonl
|
|
23
|
+
resources/unittest/pathutils/dummy.2.2.vol-2.jsonl
|
|
24
|
+
resources/unittest/pathutils/dummy.2.jsonl
|
|
25
|
+
resources/unittest/pathutils/dummy.csv.part0
|
|
26
|
+
resources/unittest/pathutils/dummy.csv.part1
|
|
27
|
+
resources/unittest/pathutils/dummy.csv.part2
|
|
28
|
+
resources/unittest/pathutils/dummy.txt
|
|
13
29
|
resources/unittest/s3utils/dir.baz/file.bar.baz
|
|
14
30
|
resources/unittest/s3utils/dir.baz/file.foo.bar
|
|
15
31
|
resources/unittest/s3utils/dir.baz/file.foo.baz
|
|
@@ -22,22 +38,6 @@ resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz
|
|
|
22
38
|
resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz
|
|
23
39
|
resources/unittest/s3utils_archive/archive.compressed.zip
|
|
24
40
|
resources/unittest/s3utils_archive/archive.uncompressed.zip
|
|
25
|
-
resources/unittest/shutils/0-dummy
|
|
26
|
-
resources/unittest/shutils/1-dummy
|
|
27
|
-
resources/unittest/shutils/2-dummy
|
|
28
|
-
resources/unittest/shutils/dummy.0.0.jsonl
|
|
29
|
-
resources/unittest/shutils/dummy.0.0.vol-0.jsonl
|
|
30
|
-
resources/unittest/shutils/dummy.0.jsonl
|
|
31
|
-
resources/unittest/shutils/dummy.1.1.jsonl
|
|
32
|
-
resources/unittest/shutils/dummy.1.1.vol-1.jsonl
|
|
33
|
-
resources/unittest/shutils/dummy.1.jsonl
|
|
34
|
-
resources/unittest/shutils/dummy.2.2.jsonl
|
|
35
|
-
resources/unittest/shutils/dummy.2.2.vol-2.jsonl
|
|
36
|
-
resources/unittest/shutils/dummy.2.jsonl
|
|
37
|
-
resources/unittest/shutils/dummy.csv.part0
|
|
38
|
-
resources/unittest/shutils/dummy.csv.part1
|
|
39
|
-
resources/unittest/shutils/dummy.csv.part2
|
|
40
|
-
resources/unittest/shutils/dummy.txt
|
|
41
41
|
src/plexus/common/__init__.py
|
|
42
42
|
src/plexus/common/pose.py
|
|
43
43
|
src/plexus/common/proj.py
|
|
@@ -57,8 +57,8 @@ src/plexus/common/utils/datautils.py
|
|
|
57
57
|
src/plexus/common/utils/dockerutils.py
|
|
58
58
|
src/plexus/common/utils/jsonutils.py
|
|
59
59
|
src/plexus/common/utils/ormutils.py
|
|
60
|
+
src/plexus/common/utils/pathutils.py
|
|
60
61
|
src/plexus/common/utils/s3utils.py
|
|
61
|
-
src/plexus/common/utils/shutils.py
|
|
62
62
|
src/plexus/common/utils/sqlutils.py
|
|
63
63
|
src/plexus/common/utils/strutils.py
|
|
64
64
|
src/plexus/common/utils/tagutils.py
|
|
@@ -69,19 +69,22 @@ src/plexus_python_common.egg-info/dependency_links.txt
|
|
|
69
69
|
src/plexus_python_common.egg-info/not-zip-safe
|
|
70
70
|
src/plexus_python_common.egg-info/requires.txt
|
|
71
71
|
src/plexus_python_common.egg-info/top_level.txt
|
|
72
|
-
test/
|
|
72
|
+
test/testenv.py
|
|
73
73
|
test/plexus_tests/__init__.py
|
|
74
|
+
test/plexus_tests/common/__init__.py
|
|
74
75
|
test/plexus_tests/common/pose_test.py
|
|
75
76
|
test/plexus_tests/common/proj_test.py
|
|
77
|
+
test/plexus_tests/common/carto/__init__.py
|
|
76
78
|
test/plexus_tests/common/carto/osm_file_test.py
|
|
77
79
|
test/plexus_tests/common/carto/osm_tags_test.py
|
|
80
|
+
test/plexus_tests/common/utils/__init__.py
|
|
78
81
|
test/plexus_tests/common/utils/bagutils_test.py
|
|
79
82
|
test/plexus_tests/common/utils/datautils_test.py
|
|
80
83
|
test/plexus_tests/common/utils/dockerutils_test.py
|
|
81
84
|
test/plexus_tests/common/utils/jsonutils_test.py
|
|
82
85
|
test/plexus_tests/common/utils/ormutils_test.py
|
|
86
|
+
test/plexus_tests/common/utils/pathutils_test.py
|
|
83
87
|
test/plexus_tests/common/utils/s3utils_test.py
|
|
84
|
-
test/plexus_tests/common/utils/shutils_test.py
|
|
85
88
|
test/plexus_tests/common/utils/strutils_test.py
|
|
86
89
|
test/plexus_tests/common/utils/tagutils_test.py
|
|
87
90
|
test/plexus_tests/common/utils/testutils_test.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -4,13 +4,12 @@ import unittest
|
|
|
4
4
|
import ddt
|
|
5
5
|
|
|
6
6
|
from plexus.common.utils.jsonutils import read_chunked_jsonl
|
|
7
|
-
from
|
|
7
|
+
from testenv import resources_directory
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@ddt.ddt
|
|
11
11
|
class JsonUtilsTest(unittest.TestCase):
|
|
12
12
|
|
|
13
13
|
def test_read_chunked_jsonl(self):
|
|
14
|
-
for data, path in read_chunked_jsonl(
|
|
15
|
-
os.path.join(resources_directory, "unittest/jsonutils", "dummy.{{}}.jsonl")):
|
|
14
|
+
for data, path in read_chunked_jsonl(str(resources_directory / "unittest" / "jsonutils" / "dummy.{{}}.jsonl")):
|
|
16
15
|
self.assertEqual(data["file"], os.path.basename(path))
|
|
@@ -30,9 +30,13 @@ from plexus.common.utils.ormutils import (
|
|
|
30
30
|
db_activate_revision_model,
|
|
31
31
|
db_activate_snapshot_model,
|
|
32
32
|
db_create_changing_model,
|
|
33
|
+
db_create_changing_models,
|
|
33
34
|
db_create_revision_model,
|
|
35
|
+
db_create_revision_models,
|
|
34
36
|
db_create_sequence_model,
|
|
37
|
+
db_create_sequence_models,
|
|
35
38
|
db_create_snapshot_model,
|
|
39
|
+
db_create_snapshot_models,
|
|
36
40
|
db_delete_sequence_model,
|
|
37
41
|
db_expire_revision_model,
|
|
38
42
|
db_expire_snapshot_model,
|
|
@@ -223,6 +227,21 @@ def test_db_sequence_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
223
227
|
results = db_read_sequence_models(session, DummySequenceModel, 0, 200)
|
|
224
228
|
assert len(results) == 0
|
|
225
229
|
|
|
230
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
231
|
+
|
|
232
|
+
results = db_create_sequence_models(session, DummySequenceModel, create_records)
|
|
233
|
+
assert len(results) == len(create_records)
|
|
234
|
+
|
|
235
|
+
for i, result in zip(range(0, 100), results):
|
|
236
|
+
assert result.sqn == i + 101
|
|
237
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
238
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
239
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
240
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
241
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
242
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
243
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
244
|
+
|
|
226
245
|
|
|
227
246
|
def test_db_changing_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
228
247
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -359,6 +378,26 @@ def test_db_changing_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
359
378
|
results = db_read_sequence_models(session, DummyChangingModel, 0, 200)
|
|
360
379
|
assert len(results) == 0
|
|
361
380
|
|
|
381
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
382
|
+
|
|
383
|
+
results = db_create_changing_models(session,
|
|
384
|
+
DummyChangingModel,
|
|
385
|
+
create_records,
|
|
386
|
+
dt_parse_iso("2024-01-01T00:00:00+00:00"))
|
|
387
|
+
assert len(results) == len(create_records)
|
|
388
|
+
|
|
389
|
+
for i, result in zip(range(0, 100), results):
|
|
390
|
+
assert result.sqn == i + 101
|
|
391
|
+
assert result.created_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
392
|
+
assert result.updated_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
393
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
394
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
395
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
396
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
397
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
398
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
399
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
400
|
+
|
|
362
401
|
|
|
363
402
|
def test_db_snapshot_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
364
403
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -644,6 +683,27 @@ def test_db_snapshot_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
644
683
|
assert result.dummy_array == update_records[i].dummy_array
|
|
645
684
|
assert result.dummy_json == update_records[i].dummy_json
|
|
646
685
|
|
|
686
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
687
|
+
|
|
688
|
+
results = db_create_snapshot_models(session,
|
|
689
|
+
DummySnapshotModel,
|
|
690
|
+
create_records,
|
|
691
|
+
dt_parse_iso("2024-01-01T00:00:00+00:00"))
|
|
692
|
+
assert len(results) == len(create_records)
|
|
693
|
+
|
|
694
|
+
for i, result in zip(range(0, 100), results):
|
|
695
|
+
assert result.sqn == i + 301
|
|
696
|
+
assert result.record_sqn == i + 301
|
|
697
|
+
assert result.created_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
698
|
+
assert result.expired_at is None
|
|
699
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
700
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
701
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
702
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
703
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
704
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
705
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
706
|
+
|
|
647
707
|
|
|
648
708
|
def test_db_revision_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
649
709
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -957,6 +1017,29 @@ def test_db_revision_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
957
1017
|
assert result.dummy_array == update_records[i].dummy_array
|
|
958
1018
|
assert result.dummy_json == update_records[i].dummy_json
|
|
959
1019
|
|
|
1020
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
1021
|
+
|
|
1022
|
+
results = db_create_revision_models(session,
|
|
1023
|
+
DummyRevisionModel,
|
|
1024
|
+
create_records,
|
|
1025
|
+
dt_parse_iso("2024-01-01T00:00:00+00:00"))
|
|
1026
|
+
assert len(results) == len(create_records)
|
|
1027
|
+
|
|
1028
|
+
for i, result in zip(range(0, 100), results):
|
|
1029
|
+
assert result.sqn == i + 301
|
|
1030
|
+
assert result.record_sqn == i + 301
|
|
1031
|
+
assert result.revision == 1
|
|
1032
|
+
assert result.created_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
1033
|
+
assert result.updated_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
1034
|
+
assert result.expired_at is None
|
|
1035
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
1036
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
1037
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
1038
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
1039
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
1040
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
1041
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
1042
|
+
|
|
960
1043
|
|
|
961
1044
|
def test_make_snapshot_model_trigger(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
962
1045
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|