plexus-python-common 1.0.15__tar.gz → 1.0.17__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.15 → plexus_python_common-1.0.17}/PKG-INFO +1 -1
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/bagutils.py +30 -33
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/ormutils.py +181 -151
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus_python_common.egg-info/PKG-INFO +1 -1
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/utils/ormutils_test.py +136 -30
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/.editorconfig +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/.github/workflows/pr.yml +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/.github/workflows/push.yml +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/.gitignore +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/MANIFEST.in +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/README.md +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/VERSION +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/pyproject.toml +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/0-dummy +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/1-dummy +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/2-dummy +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.0.0.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.0.0.vol-0.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.1.1.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.1.1.vol-1.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.2.2.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.2.2.vol-2.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.csv.part0 +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.csv.part1 +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.csv.part2 +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.txt +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/setup.cfg +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/setup.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/__init__.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMFile.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMNode.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMTags.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMWay.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/config.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/pose.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/proj.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/datautils.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/jsonutils.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/s3utils.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/shutils.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/strutils.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus_python_common.egg-info/SOURCES.txt +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus_python_common.egg-info/requires.txt +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus_python_common.egg-info/top_level.txt +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/__init__.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/pose_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/proj_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/utils/datautils_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/utils/shutils_test.py +0 -0
- {plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/utils/strutils_test.py +0 -0
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/bagutils.py
RENAMED
|
@@ -3,11 +3,8 @@ from collections.abc import Generator
|
|
|
3
3
|
from contextlib import AbstractContextManager
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
-
import sqlalchemy
|
|
7
|
-
|
|
8
|
-
from sqlalchemy import select
|
|
9
|
-
from sqlalchemy.orm import DeclarativeBase, Mapped, Session
|
|
10
|
-
from sqlalchemy.orm import mapped_column, relationship
|
|
6
|
+
import sqlalchemy as sa
|
|
7
|
+
import sqlalchemy.orm as sa_orm
|
|
11
8
|
|
|
12
9
|
__all__ = [
|
|
13
10
|
"SerializationFormat",
|
|
@@ -27,56 +24,56 @@ SerializationFormat = Literal["cdr", "cdr2", "json", "yaml"]
|
|
|
27
24
|
default_bag_db_file = "bag.db"
|
|
28
25
|
|
|
29
26
|
|
|
30
|
-
class BagBase(DeclarativeBase):
|
|
27
|
+
class BagBase(sa_orm.DeclarativeBase):
|
|
31
28
|
pass
|
|
32
29
|
|
|
33
30
|
|
|
34
31
|
class BagSchema(BagBase):
|
|
35
32
|
__tablename__ = "schema"
|
|
36
33
|
|
|
37
|
-
schema_version: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
38
|
-
ros_distro: Mapped[str] = mapped_column(String, nullable=False)
|
|
34
|
+
schema_version: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, primary_key=True)
|
|
35
|
+
ros_distro: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
39
36
|
|
|
40
37
|
|
|
41
38
|
class BagMetadata(BagBase):
|
|
42
39
|
__tablename__ = "metadata"
|
|
43
40
|
|
|
44
|
-
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
45
|
-
metadata_version: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
46
|
-
metadata_text: Mapped[str] = mapped_column(String, nullable=False)
|
|
41
|
+
id: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, primary_key=True, autoincrement=True)
|
|
42
|
+
metadata_version: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, nullable=False)
|
|
43
|
+
metadata_text: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
47
44
|
|
|
48
45
|
|
|
49
46
|
class BagTopic(BagBase):
|
|
50
47
|
__tablename__ = "topics"
|
|
51
48
|
|
|
52
|
-
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
53
|
-
name: Mapped[str] = mapped_column(String, nullable=False)
|
|
54
|
-
type: Mapped[str] = mapped_column(String, nullable=False)
|
|
55
|
-
serialization_format: Mapped[str] = mapped_column(String, nullable=False)
|
|
56
|
-
type_description_hash: Mapped[str] = mapped_column(String, nullable=False)
|
|
49
|
+
id: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, primary_key=True, autoincrement=True)
|
|
50
|
+
name: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
51
|
+
type: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
52
|
+
serialization_format: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
53
|
+
type_description_hash: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
57
54
|
|
|
58
|
-
messages: Mapped[list["BagMessage"]] = relationship("BagMessage", back_populates="topic")
|
|
55
|
+
messages: sa_orm.Mapped[list["BagMessage"]] = sa_orm.relationship("BagMessage", back_populates="topic")
|
|
59
56
|
|
|
60
57
|
|
|
61
58
|
class BagMessageDefinition(BagBase):
|
|
62
59
|
__tablename__ = "message_definitions"
|
|
63
60
|
|
|
64
|
-
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
65
|
-
topic_type: Mapped[str] = mapped_column(String, nullable=False)
|
|
66
|
-
encoding: Mapped[str] = mapped_column(String, nullable=False)
|
|
67
|
-
encoded_message_definition: Mapped[str] = mapped_column(String, nullable=False)
|
|
68
|
-
type_description_hash: Mapped[str] = mapped_column(String, nullable=False)
|
|
61
|
+
id: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, primary_key=True, autoincrement=True)
|
|
62
|
+
topic_type: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
63
|
+
encoding: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
64
|
+
encoded_message_definition: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
65
|
+
type_description_hash: sa_orm.Mapped[str] = sa_orm.mapped_column(sa.String, nullable=False)
|
|
69
66
|
|
|
70
67
|
|
|
71
68
|
class BagMessage(BagBase):
|
|
72
69
|
__tablename__ = "messages"
|
|
73
70
|
|
|
74
|
-
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
75
|
-
topic_id: Mapped[int] = mapped_column(Integer, ForeignKey("topics.id"), nullable=False)
|
|
76
|
-
timestamp: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
77
|
-
data: Mapped[bytes] = mapped_column(LargeBinary, nullable=False)
|
|
71
|
+
id: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, primary_key=True, autoincrement=True)
|
|
72
|
+
topic_id: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, sa.ForeignKey("topics.id"), nullable=False)
|
|
73
|
+
timestamp: sa_orm.Mapped[int] = sa_orm.mapped_column(sa.Integer, nullable=False)
|
|
74
|
+
data: sa_orm.Mapped[bytes] = sa_orm.mapped_column(sa.LargeBinary, nullable=False)
|
|
78
75
|
|
|
79
|
-
topic: Mapped["BagTopic"] = relationship("BagTopic", back_populates="messages")
|
|
76
|
+
topic: sa_orm.Mapped["BagTopic"] = sa_orm.relationship("BagTopic", back_populates="messages")
|
|
80
77
|
|
|
81
78
|
|
|
82
79
|
class BagReader(AbstractContextManager):
|
|
@@ -85,8 +82,8 @@ class BagReader(AbstractContextManager):
|
|
|
85
82
|
if not os.path.exists(self.db_path):
|
|
86
83
|
raise FileNotFoundError(f"could not find SQLite DB at '{db_dir}'")
|
|
87
84
|
|
|
88
|
-
self.engine =
|
|
89
|
-
self.session = Session(self.engine)
|
|
85
|
+
self.engine = sa.create_engine(f"sqlite:///{self.db_path}")
|
|
86
|
+
self.session = sa_orm.Session(self.engine)
|
|
90
87
|
self.topic_map = None
|
|
91
88
|
|
|
92
89
|
def __enter__(self):
|
|
@@ -101,7 +98,7 @@ class BagReader(AbstractContextManager):
|
|
|
101
98
|
|
|
102
99
|
def get_topics(self) -> dict[str, BagTopic]:
|
|
103
100
|
if self.topic_map is None:
|
|
104
|
-
stmt = select(BagTopic)
|
|
101
|
+
stmt = sa.select(BagTopic)
|
|
105
102
|
self.topic_map = {db_topic.name: db_topic for db_topic in self.session.scalars(stmt).all()}
|
|
106
103
|
return self.topic_map
|
|
107
104
|
|
|
@@ -111,7 +108,7 @@ class BagReader(AbstractContextManager):
|
|
|
111
108
|
begin_timestamp: int | None = None,
|
|
112
109
|
end_timestamp: int | None = None,
|
|
113
110
|
) -> Generator[BagMessage, None, None]:
|
|
114
|
-
stmt = select(BagMessage)
|
|
111
|
+
stmt = sa.select(BagMessage)
|
|
115
112
|
if topic_names is not None:
|
|
116
113
|
topic_ids = [db_topic.id for db_topic in self.get_topics().values() if db_topic.name in topic_names]
|
|
117
114
|
stmt = stmt.where(BagMessage.topic_id.in_(topic_ids))
|
|
@@ -129,8 +126,8 @@ class BagWriter(AbstractContextManager):
|
|
|
129
126
|
if os.path.exists(self.db_path):
|
|
130
127
|
os.remove(self.db_path)
|
|
131
128
|
|
|
132
|
-
self.engine =
|
|
133
|
-
self.session =
|
|
129
|
+
self.engine = sa.create_engine(f"sqlite:///{self.db_path}")
|
|
130
|
+
self.session = sa_orm.Session(self.engine)
|
|
134
131
|
self.topic_map = {}
|
|
135
132
|
|
|
136
133
|
BagBase.metadata.create_all(self.engine)
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/ormutils.py
RENAMED
|
@@ -36,6 +36,7 @@ __all__ = [
|
|
|
36
36
|
"clone_record_model_instance",
|
|
37
37
|
"clone_snapshot_model_instance",
|
|
38
38
|
"make_snapshot_model_trigger",
|
|
39
|
+
"db_make_order_by_clause",
|
|
39
40
|
"db_create_serial_model",
|
|
40
41
|
"db_create_serial_models",
|
|
41
42
|
"db_read_serial_model",
|
|
@@ -162,8 +163,7 @@ class SerialModelMixinProtocol(Protocol):
|
|
|
162
163
|
sid: int | None
|
|
163
164
|
|
|
164
165
|
|
|
165
|
-
class RecordModelMixinProtocol(
|
|
166
|
-
sid: int | None
|
|
166
|
+
class RecordModelMixinProtocol(SerialModelMixinProtocol):
|
|
167
167
|
created_at: datetime.datetime | None
|
|
168
168
|
updated_at: datetime.datetime | None
|
|
169
169
|
|
|
@@ -177,8 +177,7 @@ class RecordModelMixinProtocol(Protocol):
|
|
|
177
177
|
...
|
|
178
178
|
|
|
179
179
|
|
|
180
|
-
class SnapshotModelMixinProtocol(
|
|
181
|
-
sid: int | None
|
|
180
|
+
class SnapshotModelMixinProtocol(SerialModelMixinProtocol):
|
|
182
181
|
created_at: datetime.datetime | None
|
|
183
182
|
expired_at: datetime.datetime | None
|
|
184
183
|
record_sid: int | None
|
|
@@ -388,13 +387,18 @@ class SnapshotModel(make_base_model(), make_snapshot_model_mixin(), table=True):
|
|
|
388
387
|
pass
|
|
389
388
|
|
|
390
389
|
|
|
390
|
+
SerialModelT = TypeVar("SerialModelT", bound=SerialModelMixin)
|
|
391
|
+
RecordModelT = TypeVar("RecordModelT", bound=RecordModelMixin)
|
|
392
|
+
SnapshotModelT = TypeVar("SnapshotModelT", bound=SnapshotModelMixin)
|
|
393
|
+
|
|
394
|
+
|
|
391
395
|
def clone_serial_model_instance(
|
|
392
|
-
model: type[
|
|
396
|
+
model: type[SerialModelT],
|
|
393
397
|
instance: SerialModelMixin,
|
|
394
398
|
*,
|
|
395
399
|
clear_meta_fields: bool = True,
|
|
396
400
|
inplace: bool = False,
|
|
397
|
-
) ->
|
|
401
|
+
) -> SerialModelT:
|
|
398
402
|
result = model.model_validate(instance)
|
|
399
403
|
result = instance if inplace else result
|
|
400
404
|
if clear_meta_fields:
|
|
@@ -403,12 +407,12 @@ def clone_serial_model_instance(
|
|
|
403
407
|
|
|
404
408
|
|
|
405
409
|
def clone_record_model_instance(
|
|
406
|
-
model: type[
|
|
410
|
+
model: type[RecordModelT],
|
|
407
411
|
instance: RecordModelMixin,
|
|
408
412
|
*,
|
|
409
413
|
clear_meta_fields: bool = True,
|
|
410
414
|
inplace: bool = False,
|
|
411
|
-
) ->
|
|
415
|
+
) -> RecordModelT:
|
|
412
416
|
result = model.model_validate(instance)
|
|
413
417
|
result = instance if inplace else result
|
|
414
418
|
if clear_meta_fields:
|
|
@@ -419,12 +423,12 @@ def clone_record_model_instance(
|
|
|
419
423
|
|
|
420
424
|
|
|
421
425
|
def clone_snapshot_model_instance(
|
|
422
|
-
model: type[
|
|
426
|
+
model: type[SnapshotModelT],
|
|
423
427
|
instance: SnapshotModelMixin,
|
|
424
428
|
*,
|
|
425
429
|
clear_meta_fields: bool = True,
|
|
426
430
|
inplace: bool = False,
|
|
427
|
-
) ->
|
|
431
|
+
) -> SnapshotModelT:
|
|
428
432
|
result = model.model_validate(instance)
|
|
429
433
|
result = instance if inplace else result
|
|
430
434
|
if clear_meta_fields:
|
|
@@ -500,35 +504,48 @@ def make_snapshot_model_trigger(engine: sa.Engine, model: type[SQLModel]):
|
|
|
500
504
|
conn.execute(sa.text(create_snapshot_auto_update_trigger_sql))
|
|
501
505
|
|
|
502
506
|
|
|
507
|
+
def db_make_order_by_clause(model: type[SerialModelT], order_by: list[str] = None):
|
|
508
|
+
order_criteria = []
|
|
509
|
+
if order_by:
|
|
510
|
+
for field in order_by:
|
|
511
|
+
if field.startswith("-"):
|
|
512
|
+
order_criteria.append(sa.desc(getattr(model, field[1:])))
|
|
513
|
+
else:
|
|
514
|
+
order_criteria.append(sa.asc(getattr(model, field)))
|
|
515
|
+
else:
|
|
516
|
+
order_criteria.append(model.sid)
|
|
517
|
+
return order_criteria
|
|
518
|
+
|
|
519
|
+
|
|
503
520
|
def db_create_serial_model(
|
|
504
521
|
db: sa_orm.Session,
|
|
505
|
-
model: type[
|
|
522
|
+
model: type[SerialModelT],
|
|
506
523
|
instance: SerialModelMixin,
|
|
507
|
-
) ->
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
524
|
+
) -> SerialModelT:
|
|
525
|
+
db_instance = clone_serial_model_instance(model, instance)
|
|
526
|
+
db.add(db_instance)
|
|
527
|
+
db.flush()
|
|
511
528
|
|
|
512
529
|
return db_instance
|
|
513
530
|
|
|
514
531
|
|
|
515
532
|
def db_create_serial_models(
|
|
516
533
|
db: sa_orm.Session,
|
|
517
|
-
model: type[
|
|
534
|
+
model: type[SerialModelT],
|
|
518
535
|
instances: list[SerialModelMixin],
|
|
519
|
-
) -> list[
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
536
|
+
) -> list[SerialModelT]:
|
|
537
|
+
db_instances = [clone_serial_model_instance(model, instance) for instance in instances]
|
|
538
|
+
db.add_all(db_instances)
|
|
539
|
+
db.flush()
|
|
523
540
|
|
|
524
541
|
return db_instances
|
|
525
542
|
|
|
526
543
|
|
|
527
544
|
def db_read_serial_model(
|
|
528
545
|
db: sa_orm.Session,
|
|
529
|
-
model: type[
|
|
546
|
+
model: type[SerialModelT],
|
|
530
547
|
sid: int,
|
|
531
|
-
) ->
|
|
548
|
+
) -> SerialModelT:
|
|
532
549
|
db_instance = db.query(model).where(model.sid == sid).one_or_none()
|
|
533
550
|
if db_instance is None:
|
|
534
551
|
raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
|
|
@@ -538,136 +555,139 @@ def db_read_serial_model(
|
|
|
538
555
|
|
|
539
556
|
def db_read_serial_models(
|
|
540
557
|
db: sa_orm.Session,
|
|
541
|
-
model: type[
|
|
558
|
+
model: type[SerialModelT],
|
|
542
559
|
skip: int,
|
|
543
560
|
limit: int,
|
|
544
|
-
|
|
545
|
-
|
|
561
|
+
order_by: list[str] = None,
|
|
562
|
+
) -> list[SerialModelT]:
|
|
563
|
+
return db.query(model).order_by(*db_make_order_by_clause(model, order_by)).offset(skip).limit(limit).all()
|
|
546
564
|
|
|
547
565
|
|
|
548
566
|
def db_update_serial_model(
|
|
549
567
|
db: sa_orm.Session,
|
|
550
|
-
model: type[
|
|
568
|
+
model: type[SerialModelT],
|
|
551
569
|
instance: SerialModelMixin,
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
570
|
+
sid: int,
|
|
571
|
+
) -> SerialModelT:
|
|
572
|
+
db_instance = db.query(model).where(model.sid == sid).one_or_none()
|
|
573
|
+
if db_instance is None:
|
|
574
|
+
raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
|
|
557
575
|
|
|
558
|
-
|
|
559
|
-
|
|
576
|
+
db_instance = model_copy_from(db_instance, clone_serial_model_instance(model, instance), exclude_none=True)
|
|
577
|
+
db_instance = clone_serial_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
578
|
+
db.flush()
|
|
560
579
|
|
|
561
580
|
return db_instance
|
|
562
581
|
|
|
563
582
|
|
|
564
583
|
def db_delete_serial_model(
|
|
565
584
|
db: sa_orm.Session,
|
|
566
|
-
model: type[
|
|
585
|
+
model: type[SerialModelT],
|
|
567
586
|
sid: int,
|
|
568
|
-
) ->
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
|
|
587
|
+
) -> SerialModelT:
|
|
588
|
+
db_instance = db.query(model).where(model.sid == sid).one_or_none()
|
|
589
|
+
if db_instance is None:
|
|
590
|
+
raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
|
|
573
591
|
|
|
574
|
-
|
|
592
|
+
db.delete(db_instance)
|
|
593
|
+
db.flush()
|
|
575
594
|
|
|
576
595
|
return db_instance
|
|
577
596
|
|
|
578
597
|
|
|
579
598
|
def db_create_record_model(
|
|
580
599
|
db: sa_orm.Session,
|
|
581
|
-
model: type[
|
|
600
|
+
model: type[RecordModelT],
|
|
582
601
|
instance: RecordModelMixin,
|
|
583
602
|
created_at: datetime.datetime | None = None,
|
|
584
|
-
) ->
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
603
|
+
) -> RecordModelT:
|
|
604
|
+
db_instance = clone_record_model_instance(model, instance)
|
|
605
|
+
db_instance.created_at = created_at
|
|
606
|
+
db_instance.updated_at = created_at
|
|
607
|
+
db.add(db_instance)
|
|
608
|
+
db.flush()
|
|
590
609
|
|
|
591
610
|
return db_instance
|
|
592
611
|
|
|
593
612
|
|
|
594
613
|
def db_create_record_models(
|
|
595
614
|
db: sa_orm.Session,
|
|
596
|
-
model: type[
|
|
615
|
+
model: type[RecordModelT],
|
|
597
616
|
instances: list[RecordModelMixin],
|
|
598
617
|
created_at: datetime.datetime | None = None,
|
|
599
|
-
) -> list[
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
618
|
+
) -> list[RecordModelT]:
|
|
619
|
+
db_instances = [clone_record_model_instance(model, instance) for instance in instances]
|
|
620
|
+
for db_instance in db_instances:
|
|
621
|
+
db_instance.created_at = created_at
|
|
622
|
+
db_instance.updated_at = created_at
|
|
623
|
+
db.add_all(db_instances)
|
|
624
|
+
db.flush()
|
|
606
625
|
|
|
607
626
|
return db_instances
|
|
608
627
|
|
|
609
628
|
|
|
610
629
|
def db_update_record_model(
|
|
611
630
|
db: sa_orm.Session,
|
|
612
|
-
model: type[
|
|
631
|
+
model: type[RecordModelT],
|
|
613
632
|
instance: RecordModelMixin,
|
|
614
633
|
sid: int,
|
|
615
634
|
updated_at: datetime.datetime,
|
|
616
|
-
) ->
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
|
|
635
|
+
) -> RecordModelT:
|
|
636
|
+
db_instance = db.query(model).where(model.sid == sid).one_or_none()
|
|
637
|
+
if db_instance is None:
|
|
638
|
+
raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
|
|
621
639
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
640
|
+
db_instance = model_copy_from(db_instance, clone_record_model_instance(model, instance), exclude_none=True)
|
|
641
|
+
db_instance.updated_at = updated_at
|
|
642
|
+
db_instance = clone_record_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
643
|
+
db.flush()
|
|
625
644
|
|
|
626
645
|
return db_instance
|
|
627
646
|
|
|
628
647
|
|
|
629
648
|
def db_create_snapshot_model(
|
|
630
649
|
db: sa_orm.Session,
|
|
631
|
-
model: type[
|
|
650
|
+
model: type[SnapshotModelT],
|
|
632
651
|
instance: SnapshotModelMixin,
|
|
633
652
|
created_at: datetime.datetime,
|
|
634
|
-
) ->
|
|
635
|
-
|
|
636
|
-
|
|
653
|
+
) -> SnapshotModelT:
|
|
654
|
+
db_instance = clone_snapshot_model_instance(model, instance)
|
|
655
|
+
db_instance.created_at = created_at
|
|
656
|
+
db_instance.expired_at = None
|
|
657
|
+
db.add(db_instance)
|
|
658
|
+
db.flush()
|
|
637
659
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
db.add(db_instance)
|
|
641
|
-
db.flush([db_instance])
|
|
642
|
-
db_instance.record_sid = db_instance.sid
|
|
660
|
+
db_instance.record_sid = db_instance.sid
|
|
661
|
+
db.flush()
|
|
643
662
|
|
|
644
663
|
return db_instance
|
|
645
664
|
|
|
646
665
|
|
|
647
666
|
def db_create_snapshot_models(
|
|
648
667
|
db: sa_orm.Session,
|
|
649
|
-
model: type[
|
|
668
|
+
model: type[SnapshotModelT],
|
|
650
669
|
instances: list[SnapshotModelMixin],
|
|
651
670
|
created_at: datetime.datetime,
|
|
652
|
-
) -> list[
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
671
|
+
) -> list[SnapshotModelT]:
|
|
672
|
+
db_instances = [clone_snapshot_model_instance(model, instance) for instance in instances]
|
|
673
|
+
for db_instance in db_instances:
|
|
674
|
+
db_instance.created_at = created_at
|
|
675
|
+
db_instance.expired_at = None
|
|
676
|
+
db.add_all(db_instances)
|
|
677
|
+
db.flush()
|
|
678
|
+
|
|
679
|
+
for db_instance in db_instances:
|
|
680
|
+
db_instance.record_sid = db_instance.sid
|
|
681
|
+
db.flush()
|
|
662
682
|
|
|
663
683
|
return db_instances
|
|
664
684
|
|
|
665
685
|
|
|
666
686
|
def db_read_snapshot_models_of_record(
|
|
667
687
|
db: sa_orm.Session,
|
|
668
|
-
model: type[
|
|
688
|
+
model: type[SnapshotModelT],
|
|
669
689
|
record_sid: int,
|
|
670
|
-
) -> list[
|
|
690
|
+
) -> list[SnapshotModelT]:
|
|
671
691
|
return (
|
|
672
692
|
db
|
|
673
693
|
.query(model)
|
|
@@ -679,9 +699,9 @@ def db_read_snapshot_models_of_record(
|
|
|
679
699
|
|
|
680
700
|
def db_read_latest_snapshot_model_of_record(
|
|
681
701
|
db: sa_orm.Session,
|
|
682
|
-
model: type[
|
|
702
|
+
model: type[SnapshotModelT],
|
|
683
703
|
record_sid: int,
|
|
684
|
-
) ->
|
|
704
|
+
) -> SnapshotModelT:
|
|
685
705
|
db_instance = (
|
|
686
706
|
db
|
|
687
707
|
.query(model)
|
|
@@ -697,9 +717,9 @@ def db_read_latest_snapshot_model_of_record(
|
|
|
697
717
|
|
|
698
718
|
def db_read_active_snapshot_model_of_record(
|
|
699
719
|
db: sa_orm.Session,
|
|
700
|
-
model: type[
|
|
720
|
+
model: type[SnapshotModelT],
|
|
701
721
|
record_sid: int,
|
|
702
|
-
) ->
|
|
722
|
+
) -> SnapshotModelT:
|
|
703
723
|
db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
|
|
704
724
|
if db_instance is None:
|
|
705
725
|
raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
|
|
@@ -709,24 +729,25 @@ def db_read_active_snapshot_model_of_record(
|
|
|
709
729
|
|
|
710
730
|
def db_read_expired_snapshot_models_of_record(
|
|
711
731
|
db: sa_orm.Session,
|
|
712
|
-
model: type[
|
|
732
|
+
model: type[SnapshotModelT],
|
|
713
733
|
record_sid: int,
|
|
714
|
-
) -> list[
|
|
734
|
+
) -> list[SnapshotModelT]:
|
|
715
735
|
return (
|
|
716
736
|
db
|
|
717
737
|
.query(model)
|
|
718
738
|
.where(model.record_sid == record_sid, model.expired_at.is_not(None))
|
|
719
|
-
.order_by(model.
|
|
739
|
+
.order_by(model.created_at.desc())
|
|
720
740
|
.all()
|
|
721
741
|
)
|
|
722
742
|
|
|
723
743
|
|
|
724
744
|
def db_read_latest_snapshot_models(
|
|
725
745
|
db: sa_orm.Session,
|
|
726
|
-
model: type[
|
|
746
|
+
model: type[SnapshotModelT],
|
|
727
747
|
skip: int,
|
|
728
748
|
limit: int,
|
|
729
|
-
|
|
749
|
+
order_by: list[str] = None,
|
|
750
|
+
) -> list[SnapshotModelT]:
|
|
730
751
|
subquery = (
|
|
731
752
|
db
|
|
732
753
|
.query(model.record_sid,
|
|
@@ -740,7 +761,7 @@ def db_read_latest_snapshot_models(
|
|
|
740
761
|
.query(model)
|
|
741
762
|
.join(subquery,
|
|
742
763
|
sa.and_(model.record_sid == subquery.c.record_sid, model.created_at == subquery.c.max_created_at))
|
|
743
|
-
.order_by(model
|
|
764
|
+
.order_by(*db_make_order_by_clause(model, order_by))
|
|
744
765
|
.offset(skip)
|
|
745
766
|
.limit(limit)
|
|
746
767
|
.all()
|
|
@@ -749,88 +770,97 @@ def db_read_latest_snapshot_models(
|
|
|
749
770
|
|
|
750
771
|
def db_read_active_snapshot_models(
|
|
751
772
|
db: sa_orm.Session,
|
|
752
|
-
model: type[
|
|
773
|
+
model: type[SnapshotModelT],
|
|
753
774
|
skip: int,
|
|
754
775
|
limit: int,
|
|
755
|
-
|
|
756
|
-
|
|
776
|
+
order_by: list[str] = None,
|
|
777
|
+
) -> list[SnapshotModelT]:
|
|
778
|
+
return (
|
|
779
|
+
db
|
|
780
|
+
.query(model)
|
|
781
|
+
.where(model.expired_at.is_(None))
|
|
782
|
+
.order_by(*db_make_order_by_clause(model, order_by))
|
|
783
|
+
.offset(skip)
|
|
784
|
+
.limit(limit)
|
|
785
|
+
.all()
|
|
786
|
+
)
|
|
757
787
|
|
|
758
788
|
|
|
759
789
|
def db_update_snapshot_model(
|
|
760
790
|
db: sa_orm.Session,
|
|
761
|
-
model: type[
|
|
791
|
+
model: type[SnapshotModelT],
|
|
762
792
|
instance: SnapshotModelMixin,
|
|
763
793
|
record_sid: int,
|
|
764
794
|
updated_at: datetime.datetime,
|
|
765
|
-
) ->
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
|
|
795
|
+
) -> SnapshotModelT:
|
|
796
|
+
db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
|
|
797
|
+
if db_instance is None:
|
|
798
|
+
raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
|
|
770
799
|
|
|
771
|
-
|
|
772
|
-
|
|
800
|
+
db_instance.expired_at = updated_at
|
|
801
|
+
db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
802
|
+
db.flush()
|
|
773
803
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
804
|
+
db_new_instance = clone_snapshot_model_instance(model, instance)
|
|
805
|
+
db_new_instance.record_sid = record_sid
|
|
806
|
+
db_new_instance.created_at = updated_at
|
|
807
|
+
db_new_instance.expired_at = None
|
|
808
|
+
db.add(db_new_instance)
|
|
809
|
+
db.flush()
|
|
779
810
|
|
|
780
811
|
return db_new_instance
|
|
781
812
|
|
|
782
813
|
|
|
783
814
|
def db_expire_snapshot_model(
|
|
784
815
|
db: sa_orm.Session,
|
|
785
|
-
model: type[
|
|
816
|
+
model: type[SnapshotModelT],
|
|
786
817
|
record_sid: int,
|
|
787
818
|
updated_at: datetime.datetime,
|
|
788
|
-
) ->
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
|
|
819
|
+
) -> SnapshotModelT:
|
|
820
|
+
db_instance = (
|
|
821
|
+
db
|
|
822
|
+
.query(model)
|
|
823
|
+
.where(model.record_sid == record_sid, model.expired_at.is_(None))
|
|
824
|
+
.one_or_none()
|
|
825
|
+
)
|
|
826
|
+
if db_instance is None:
|
|
827
|
+
raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
|
|
798
828
|
|
|
799
|
-
|
|
800
|
-
|
|
829
|
+
db_instance.expired_at = updated_at
|
|
830
|
+
db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
831
|
+
db.flush()
|
|
801
832
|
|
|
802
833
|
return db_instance
|
|
803
834
|
|
|
804
835
|
|
|
805
836
|
def db_activate_snapshot_model(
|
|
806
837
|
db: sa_orm.Session,
|
|
807
|
-
model: type[
|
|
838
|
+
model: type[SnapshotModelT],
|
|
808
839
|
record_sid: int,
|
|
809
840
|
updated_at: datetime.datetime,
|
|
810
|
-
) ->
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
db.add(db_new_instance)
|
|
841
|
+
) -> SnapshotModelT:
|
|
842
|
+
db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
|
|
843
|
+
if db_instance is not None:
|
|
844
|
+
raise sa_exc.MultipleResultsFound(f"Active '{model}' of specified record_sid '{record_sid}' already exists")
|
|
845
|
+
|
|
846
|
+
db_instance = (
|
|
847
|
+
db
|
|
848
|
+
.query(model)
|
|
849
|
+
.where(model.record_sid == record_sid, model.expired_at.is_not(None))
|
|
850
|
+
.order_by(model.created_at.desc())
|
|
851
|
+
.first()
|
|
852
|
+
)
|
|
853
|
+
if db_instance is None:
|
|
854
|
+
raise sa_exc.NoResultFound(f"Expired '{model}' of specified record_sid '{record_sid}' not found")
|
|
855
|
+
|
|
856
|
+
db_new_instance = clone_snapshot_model_instance(model, db_instance)
|
|
857
|
+
db_new_instance.record_sid = record_sid
|
|
858
|
+
db_new_instance.created_at = db_instance.expired_at
|
|
859
|
+
db_new_instance.expired_at = updated_at
|
|
860
|
+
db_new_instance = clone_snapshot_model_instance(model, db_new_instance, clear_meta_fields=False, inplace=True)
|
|
861
|
+
db_new_instance.created_at = updated_at
|
|
862
|
+
db_new_instance.expired_at = None
|
|
863
|
+
db.add(db_new_instance)
|
|
864
|
+
db.flush()
|
|
835
865
|
|
|
836
866
|
return db_new_instance
|
|
@@ -10,11 +10,12 @@ from iker.common.utils.dbutils import make_scheme
|
|
|
10
10
|
from iker.common.utils.dtutils import dt_parse_iso
|
|
11
11
|
from iker.common.utils.jsonutils import JsonType
|
|
12
12
|
from iker.common.utils.randutils import randomizer
|
|
13
|
-
from sqlmodel import Field
|
|
13
|
+
from sqlmodel import Field, SQLModel
|
|
14
14
|
|
|
15
15
|
from plexus.common.utils.ormutils import (
|
|
16
16
|
db_activate_snapshot_model,
|
|
17
17
|
db_create_record_model,
|
|
18
|
+
db_create_serial_model,
|
|
18
19
|
db_create_snapshot_model,
|
|
19
20
|
db_delete_serial_model,
|
|
20
21
|
db_expire_snapshot_model,
|
|
@@ -26,6 +27,7 @@ from plexus.common.utils.ormutils import (
|
|
|
26
27
|
db_read_serial_models,
|
|
27
28
|
db_read_snapshot_models_of_record,
|
|
28
29
|
db_update_record_model,
|
|
30
|
+
db_update_serial_model,
|
|
29
31
|
db_update_snapshot_model,
|
|
30
32
|
)
|
|
31
33
|
from plexus.common.utils.ormutils import (
|
|
@@ -44,48 +46,151 @@ fixture_postgresql_test = pytest_postgresql.factories.postgresql("fixture_postgr
|
|
|
44
46
|
DummyBaseModel = make_base_model()
|
|
45
47
|
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
def make_dummy_model():
|
|
50
|
+
class Model(SQLModel):
|
|
51
|
+
dummy_str: str = Field(sa_column=sa.Column(sa_pg.VARCHAR(256)), default="")
|
|
52
|
+
dummy_int: int = Field(sa_column=sa.Column(sa_pg.BIGINT), default=0)
|
|
53
|
+
dummy_float: float = Field(sa_column=sa.Column(sa_pg.DOUBLE_PRECISION), default=0.0)
|
|
54
|
+
dummy_bool: bool = Field(sa_column=sa.Column(sa_pg.BOOLEAN), default=False)
|
|
55
|
+
dummy_array: list[str] = Field(sa_column=sa.Column(sa_pg.ARRAY(sa_pg.VARCHAR(64))))
|
|
56
|
+
dummy_json: JsonType = Field(sa_column=sa.Column(sa_pg.JSONB))
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
dummy_int: int = Field(sa_column=sa.Column(sa_pg.BIGINT), default=0)
|
|
52
|
-
dummy_float: float = Field(sa_column=sa.Column(sa_pg.DOUBLE_PRECISION), default=0.0)
|
|
53
|
-
dummy_bool: bool = Field(sa_column=sa.Column(sa_pg.BOOLEAN), default=False)
|
|
54
|
-
dummy_array: list[str] = Field(sa_column=sa.Column(sa_pg.ARRAY(sa_pg.VARCHAR(64))))
|
|
55
|
-
dummy_json: JsonType = Field(sa_column=sa.Column(sa_pg.JSONB))
|
|
58
|
+
return Model
|
|
56
59
|
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
__tablename__ = "dummy_record_model"
|
|
61
|
+
DummyModel = make_dummy_model()
|
|
60
62
|
|
|
61
|
-
dummy_str: str = Field(sa_column=sa.Column(sa_pg.VARCHAR(256)), default="")
|
|
62
|
-
dummy_int: int = Field(sa_column=sa.Column(sa_pg.BIGINT), default=0)
|
|
63
|
-
dummy_float: float = Field(sa_column=sa.Column(sa_pg.DOUBLE_PRECISION), default=0.0)
|
|
64
|
-
dummy_bool: bool = Field(sa_column=sa.Column(sa_pg.BOOLEAN), default=False)
|
|
65
|
-
dummy_array: list[str] = Field(sa_column=sa.Column(sa_pg.ARRAY(sa_pg.VARCHAR(64))))
|
|
66
|
-
dummy_json: JsonType = Field(sa_column=sa.Column(sa_pg.JSONB))
|
|
67
63
|
|
|
64
|
+
class DummySerialModel(DummyBaseModel, make_dummy_model(), make_serial_model_mixin(), table=True):
|
|
65
|
+
__tablename__ = "dummy_serial_model"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class DummyRecordModel(DummyBaseModel, make_dummy_model(), make_record_model_mixin(), table=True):
|
|
69
|
+
__tablename__ = "dummy_record_model"
|
|
68
70
|
__table_args__ = (
|
|
69
71
|
record_model_mixin.make_index_created_at("ix_dummy_record_model_created_at"),
|
|
70
72
|
)
|
|
71
73
|
|
|
72
74
|
|
|
73
|
-
class DummySnapshotModel(DummyBaseModel, make_snapshot_model_mixin(), table=True):
|
|
75
|
+
class DummySnapshotModel(DummyBaseModel, make_dummy_model(), make_snapshot_model_mixin(), table=True):
|
|
74
76
|
__tablename__ = "dummy_snapshot_model"
|
|
75
|
-
|
|
76
|
-
dummy_str: str = Field(sa_column=sa.Column(sa_pg.VARCHAR(256)), default="")
|
|
77
|
-
dummy_int: int = Field(sa_column=sa.Column(sa_pg.BIGINT), default=0)
|
|
78
|
-
dummy_float: float = Field(sa_column=sa.Column(sa_pg.DOUBLE_PRECISION), default=0.0)
|
|
79
|
-
dummy_bool: bool = Field(sa_column=sa.Column(sa_pg.BOOLEAN), default=False)
|
|
80
|
-
dummy_array: list[str] = Field(sa_column=sa.Column(sa_pg.ARRAY(sa_pg.VARCHAR(64))))
|
|
81
|
-
dummy_json: JsonType = Field(sa_column=sa.Column(sa_pg.JSONB))
|
|
82
|
-
|
|
83
77
|
__table_args__ = (
|
|
84
78
|
snapshot_model_mixin.make_index_created_at_expired_at("ix_dummy_snapshot_model_created_at_expired_at"),
|
|
85
79
|
snapshot_model_mixin.make_active_unique_index_record_sid("ix_au_dummy_snapshot_model_record_sid"),
|
|
86
80
|
)
|
|
87
81
|
|
|
88
82
|
|
|
83
|
+
def test_db_serial_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
84
|
+
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
85
|
+
host = fixture_postgresql_test.info.host
|
|
86
|
+
port = fixture_postgresql_test.info.port
|
|
87
|
+
user = fixture_postgresql_test.info.user
|
|
88
|
+
database = fixture_postgresql_test.info.dbname
|
|
89
|
+
|
|
90
|
+
maker = ConnectionMaker.create(scheme,
|
|
91
|
+
host,
|
|
92
|
+
port,
|
|
93
|
+
user,
|
|
94
|
+
None,
|
|
95
|
+
database,
|
|
96
|
+
session_opts=dict(expire_on_commit=False))
|
|
97
|
+
|
|
98
|
+
DummyBaseModel.metadata.create_all(maker.engine)
|
|
99
|
+
|
|
100
|
+
rng = randomizer()
|
|
101
|
+
|
|
102
|
+
def random_record() -> DummyModel:
|
|
103
|
+
return DummyModel(
|
|
104
|
+
dummy_int=rng.next_int(0, 1000),
|
|
105
|
+
dummy_str=rng.random_alphanumeric(rng.next_int(10, 20)),
|
|
106
|
+
dummy_float=rng.next_float(0.0, 100.0),
|
|
107
|
+
dummy_bool=rng.next_bool(),
|
|
108
|
+
dummy_array=list(rng.random_ascii(rng.next_int(10, 20)) for _ in range(rng.next_int(10, 20))),
|
|
109
|
+
dummy_json=rng.random_json_object(5),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
with maker.make_session() as session:
|
|
113
|
+
session.execute(sa.sql.text("SET TIMEZONE TO 'UTC'"))
|
|
114
|
+
session.commit()
|
|
115
|
+
|
|
116
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
117
|
+
update_records = [random_record() for _ in range(0, 100)]
|
|
118
|
+
|
|
119
|
+
for i in range(0, 100):
|
|
120
|
+
with pytest.raises(sa_exc.NoResultFound):
|
|
121
|
+
db_read_serial_model(session, DummySerialModel, i + 1)
|
|
122
|
+
|
|
123
|
+
for i in range(0, 100):
|
|
124
|
+
result = db_create_serial_model(session, DummySerialModel, create_records[i])
|
|
125
|
+
|
|
126
|
+
assert result.sid == i + 1
|
|
127
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
128
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
129
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
130
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
131
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
132
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
133
|
+
|
|
134
|
+
for i in range(0, 100):
|
|
135
|
+
result = db_read_serial_model(session, DummySerialModel, i + 1)
|
|
136
|
+
|
|
137
|
+
assert result.sid == i + 1
|
|
138
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
139
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
140
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
141
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
142
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
143
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
144
|
+
|
|
145
|
+
for i in range(0, 100):
|
|
146
|
+
result = db_update_serial_model(session, DummySerialModel, update_records[i], i + 1)
|
|
147
|
+
|
|
148
|
+
assert result.sid == i + 1
|
|
149
|
+
assert result.dummy_int == update_records[i].dummy_int
|
|
150
|
+
assert result.dummy_str == update_records[i].dummy_str
|
|
151
|
+
assert result.dummy_float == update_records[i].dummy_float
|
|
152
|
+
assert result.dummy_bool == update_records[i].dummy_bool
|
|
153
|
+
assert result.dummy_array == update_records[i].dummy_array
|
|
154
|
+
assert result.dummy_json == update_records[i].dummy_json
|
|
155
|
+
|
|
156
|
+
results = db_read_serial_models(session, DummySerialModel, 0, 200)
|
|
157
|
+
assert len(results) == 100
|
|
158
|
+
|
|
159
|
+
for i, (result, update_record) in enumerate(zip(results, update_records)):
|
|
160
|
+
assert result.sid == i + 1
|
|
161
|
+
assert result.dummy_int == update_record.dummy_int
|
|
162
|
+
assert result.dummy_str == update_record.dummy_str
|
|
163
|
+
assert result.dummy_float == update_record.dummy_float
|
|
164
|
+
assert result.dummy_bool == update_record.dummy_bool
|
|
165
|
+
assert result.dummy_array == update_record.dummy_array
|
|
166
|
+
assert result.dummy_json == update_record.dummy_json
|
|
167
|
+
|
|
168
|
+
for i in range(0, 100):
|
|
169
|
+
result = db_read_serial_model(session, DummySerialModel, i + 1)
|
|
170
|
+
|
|
171
|
+
assert result.sid == i + 1
|
|
172
|
+
assert result.dummy_int == update_records[i].dummy_int
|
|
173
|
+
assert result.dummy_str == update_records[i].dummy_str
|
|
174
|
+
assert result.dummy_float == update_records[i].dummy_float
|
|
175
|
+
assert result.dummy_bool == update_records[i].dummy_bool
|
|
176
|
+
assert result.dummy_array == update_records[i].dummy_array
|
|
177
|
+
assert result.dummy_json == update_records[i].dummy_json
|
|
178
|
+
|
|
179
|
+
for i in range(0, 100):
|
|
180
|
+
result = db_delete_serial_model(session, DummySerialModel, i + 1)
|
|
181
|
+
|
|
182
|
+
assert result.sid == i + 1
|
|
183
|
+
assert result.dummy_int == update_records[i].dummy_int
|
|
184
|
+
assert result.dummy_str == update_records[i].dummy_str
|
|
185
|
+
assert result.dummy_float == update_records[i].dummy_float
|
|
186
|
+
assert result.dummy_bool == update_records[i].dummy_bool
|
|
187
|
+
assert result.dummy_array == update_records[i].dummy_array
|
|
188
|
+
assert result.dummy_json == update_records[i].dummy_json
|
|
189
|
+
|
|
190
|
+
results = db_read_serial_models(session, DummySerialModel, 0, 200)
|
|
191
|
+
assert len(results) == 0
|
|
192
|
+
|
|
193
|
+
|
|
89
194
|
def test_db_record_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
90
195
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
91
196
|
host = fixture_postgresql_test.info.host
|
|
@@ -105,8 +210,8 @@ def test_db_record_model_crud(fixture_postgresql_test_proc, fixture_postgresql_t
|
|
|
105
210
|
|
|
106
211
|
rng = randomizer()
|
|
107
212
|
|
|
108
|
-
def random_record() ->
|
|
109
|
-
return
|
|
213
|
+
def random_record() -> DummyModel:
|
|
214
|
+
return DummyModel(
|
|
110
215
|
dummy_int=rng.next_int(0, 1000),
|
|
111
216
|
dummy_str=rng.random_alphanumeric(rng.next_int(10, 20)),
|
|
112
217
|
dummy_float=rng.next_float(0.0, 100.0),
|
|
@@ -215,6 +320,7 @@ def test_db_record_model_crud(fixture_postgresql_test_proc, fixture_postgresql_t
|
|
|
215
320
|
results = db_read_serial_models(session, DummyRecordModel, 0, 200)
|
|
216
321
|
assert len(results) == 0
|
|
217
322
|
|
|
323
|
+
|
|
218
324
|
def test_db_snapshot_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
219
325
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
220
326
|
host = fixture_postgresql_test.info.host
|
|
@@ -235,8 +341,8 @@ def test_db_snapshot_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
235
341
|
|
|
236
342
|
rng = randomizer()
|
|
237
343
|
|
|
238
|
-
def random_record() ->
|
|
239
|
-
return
|
|
344
|
+
def random_record() -> DummyModel:
|
|
345
|
+
return DummyModel(
|
|
240
346
|
dummy_int=rng.next_int(0, 1000),
|
|
241
347
|
dummy_str=rng.random_alphanumeric(rng.next_int(10, 20)),
|
|
242
348
|
dummy_float=rng.next_float(0.0, 100.0),
|
|
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
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/0-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/1-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/2-dummy
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.0.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.1.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.2.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/resources/unittest/shutils/dummy.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMFile.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMNode.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMTags.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/OSMWay.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/carto/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/__init__.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/datautils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/jsonutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/s3utils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/shutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/src/plexus/common/utils/strutils.py
RENAMED
|
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
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/pose_test.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.15 → plexus_python_common-1.0.17}/test/plexus_tests/common/proj_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|