plexus-python-common 1.0.27__tar.gz → 1.0.29__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.
Files changed (93) hide show
  1. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/PKG-INFO +7 -4
  2. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/pyproject.toml +12 -6
  3. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.baz/file.bar.baz +16 -0
  4. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.baz/file.foo.bar +16 -0
  5. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.baz/file.foo.baz +16 -0
  6. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +16 -0
  7. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +16 -0
  8. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +16 -0
  9. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +16 -0
  10. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/file.bar +16 -0
  11. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/file.baz +16 -0
  12. plexus_python_common-1.0.29/resources/unittest/s3utils/dir.foo/file.foo +16 -0
  13. plexus_python_common-1.0.29/resources/unittest/s3utils_archive/archive.compressed.zip +0 -0
  14. plexus_python_common-1.0.29/resources/unittest/s3utils_archive/archive.uncompressed.zip +0 -0
  15. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/ormutils.py +44 -38
  16. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/s3utils.py +217 -1
  17. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus_python_common.egg-info/PKG-INFO +7 -4
  18. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus_python_common.egg-info/SOURCES.txt +2 -0
  19. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus_python_common.egg-info/requires.txt +6 -3
  20. plexus_python_common-1.0.29/test/plexus_tests/common/utils/s3utils_test.py +651 -0
  21. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
  22. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
  23. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
  24. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
  25. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
  26. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
  27. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
  28. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/file.bar +0 -0
  29. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/file.baz +0 -0
  30. plexus_python_common-1.0.27/resources/unittest/s3utils/dir.foo/file.foo +0 -0
  31. plexus_python_common-1.0.27/test/plexus_tests/common/utils/s3utils_test.py +0 -458
  32. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/.editorconfig +0 -0
  33. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/.github/workflows/pr.yml +0 -0
  34. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/.github/workflows/push.yml +0 -0
  35. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/.gitignore +0 -0
  36. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/MANIFEST.in +0 -0
  37. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/README.md +0 -0
  38. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/VERSION +0 -0
  39. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
  40. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
  41. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
  42. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/0-dummy +0 -0
  43. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/1-dummy +0 -0
  44. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/2-dummy +0 -0
  45. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.0.0.jsonl +0 -0
  46. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.0.0.vol-0.jsonl +0 -0
  47. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.0.jsonl +0 -0
  48. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.1.1.jsonl +0 -0
  49. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.1.1.vol-1.jsonl +0 -0
  50. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.1.jsonl +0 -0
  51. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.2.2.jsonl +0 -0
  52. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.2.2.vol-2.jsonl +0 -0
  53. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.2.jsonl +0 -0
  54. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.csv.part0 +0 -0
  55. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.csv.part1 +0 -0
  56. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.csv.part2 +0 -0
  57. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/resources/unittest/shutils/dummy.txt +0 -0
  58. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/setup.cfg +0 -0
  59. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/setup.py +0 -0
  60. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/__init__.py +0 -0
  61. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/carto/OSMFile.py +0 -0
  62. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/carto/OSMNode.py +0 -0
  63. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/carto/OSMTags.py +0 -0
  64. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/carto/OSMWay.py +0 -0
  65. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/carto/__init__.py +0 -0
  66. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/pose.py +0 -0
  67. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/proj.py +0 -0
  68. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/__init__.py +0 -0
  69. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/apiutils.py +0 -0
  70. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/bagutils.py +0 -0
  71. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/config.py +0 -0
  72. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/datautils.py +0 -0
  73. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/jsonutils.py +0 -0
  74. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/shutils.py +0 -0
  75. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/sqlutils.py +0 -0
  76. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/strutils.py +0 -0
  77. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus/common/utils/testutils.py +0 -0
  78. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
  79. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
  80. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/src/plexus_python_common.egg-info/top_level.txt +0 -0
  81. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_test.py +0 -0
  82. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/__init__.py +0 -0
  83. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
  84. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
  85. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/pose_test.py +0 -0
  86. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/proj_test.py +0 -0
  87. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
  88. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/datautils_test.py +0 -0
  89. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
  90. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/ormutils_test.py +0 -0
  91. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/shutils_test.py +0 -0
  92. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/strutils_test.py +0 -0
  93. {plexus_python_common-1.0.27 → plexus_python_common-1.0.29}/test/plexus_tests/common/utils/testutils_test.py +0 -0
@@ -1,14 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plexus-python-common
3
- Version: 1.0.27
3
+ Version: 1.0.29
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.12
6
6
  Classifier: Programming Language :: Python :: 3.13
7
7
  Classifier: Programming Language :: Python :: 3.14
8
8
  Requires-Python: <3.15,>=3.12
9
- Requires-Dist: boto3>=1.41
10
- Requires-Dist: boto3-stubs>=1.41
9
+ Requires-Dist: aiobotocore<2.27,>=2.26
10
+ Requires-Dist: boto3<1.42,>=1.41
11
+ Requires-Dist: boto3-stubs<1.42,>=1.41
11
12
  Requires-Dist: cloudpathlib>=0.21
13
+ Requires-Dist: fsspec>=2025.10
12
14
  Requires-Dist: lxml>=6.0
13
15
  Requires-Dist: numpy>=2.3
14
16
  Requires-Dist: pydantic>=2.8
@@ -17,6 +19,7 @@ Requires-Dist: pyparsing>=3.2
17
19
  Requires-Dist: pyproj>=3.6
18
20
  Requires-Dist: pyquaternion>=0.9
19
21
  Requires-Dist: sqlalchemy>=2.0
22
+ Requires-Dist: s3fs>=2025.10
20
23
  Requires-Dist: rich>=13.9
21
24
  Requires-Dist: textcase>=0.4
22
25
  Requires-Dist: ujson>=5.9
@@ -28,7 +31,7 @@ Requires-Dist: fastapi>=0.119.0; extra == "api"
28
31
  Requires-Dist: sqlmodel>=0.0.25; extra == "api"
29
32
  Provides-Extra: test
30
33
  Requires-Dist: ddt>=1.7; extra == "test"
31
- Requires-Dist: moto[all,ec2,s3]>=5.1; extra == "test"
34
+ Requires-Dist: moto[s3,server]>=5.1; extra == "test"
32
35
  Requires-Dist: pytest-cov>=5.0; extra == "test"
33
36
  Requires-Dist: pytest-order>=1.3; extra == "test"
34
37
  Requires-Dist: pytest-postgresql>=6.1; extra == "test"
@@ -8,9 +8,11 @@ build-backend = "setuptools.build_meta"
8
8
 
9
9
  [dependency-groups]
10
10
  dev = [
11
- "boto3>=1.41",
12
- "boto3-stubs>=1.41",
11
+ "aiobotocore>=2.26,<2.27",
12
+ "boto3>=1.41,<1.42",
13
+ "boto3-stubs>=1.41,<1.42",
13
14
  "cloudpathlib>=0.21",
15
+ "fsspec>=2025.10",
14
16
  "lxml>=6.0",
15
17
  "numpy>=2.3",
16
18
  "pydantic>=2.8",
@@ -19,6 +21,7 @@ dev = [
19
21
  "pyproj>=3.6",
20
22
  "pyquaternion>=0.9",
21
23
  "sqlalchemy>=2.0",
24
+ "s3fs>=2025.10",
22
25
  "rich>=13.9",
23
26
  "textcase>=0.4",
24
27
  "ujson>=5.9",
@@ -30,7 +33,7 @@ api = [
30
33
  ]
31
34
  test = [
32
35
  "ddt>=1.7",
33
- "moto[ec2,s3,all]>=5.1",
36
+ "moto[server,s3]>=5.1",
34
37
  "pytest-cov>=5.0",
35
38
  "pytest-order>=1.3",
36
39
  "pytest-postgresql>=6.1",
@@ -48,9 +51,11 @@ classifiers = [
48
51
  "Programming Language :: Python :: 3.14",
49
52
  ]
50
53
  dependencies = [
51
- "boto3>=1.41",
52
- "boto3-stubs>=1.41",
54
+ "aiobotocore>=2.26,<2.27",
55
+ "boto3>=1.41,<1.42",
56
+ "boto3-stubs>=1.41,<1.42",
53
57
  "cloudpathlib>=0.21",
58
+ "fsspec>=2025.10",
54
59
  "lxml>=6.0",
55
60
  "numpy>=2.3",
56
61
  "pydantic>=2.8",
@@ -59,6 +64,7 @@ dependencies = [
59
64
  "pyproj>=3.6",
60
65
  "pyquaternion>=0.9",
61
66
  "sqlalchemy>=2.0",
67
+ "s3fs>=2025.10",
62
68
  "rich>=13.9",
63
69
  "textcase>=0.4",
64
70
  "ujson>=5.9",
@@ -75,7 +81,7 @@ api = [
75
81
  ]
76
82
  test = [
77
83
  "ddt>=1.7",
78
- "moto[ec2,s3,all]>=5.1",
84
+ "moto[server,s3]>=5.1",
79
85
  "pytest-cov>=5.0",
80
86
  "pytest-order>=1.3",
81
87
  "pytest-postgresql>=6.1",
@@ -0,0 +1,16 @@
1
+ a8a02100e9c056a268ab37eab24e779e48fede1876b84ed3c7ca8ab85deeaeca
2
+ 79e97fdca8f0654e868cc8df06cf6b6cfe9d462c840711dbf42a8607919701a7
3
+ 77c3748acb005e2f629a80b8040163365f37804d4b0e174ddb1ecf3a535397ec
4
+ 0491153226b97cad16810e00e29af54141390b3778902ca5bf10636f0ceb4517
5
+ 4c087fe45d4da13a4098a4d28429d4db44cffd5a1e74712e153528235ea4edae
6
+ a6e92325d196f396e47b2359de8b8f42616dac799c2f902fa65af403b1b5f4da
7
+ 20ba5f1f9d22c9b872fe6fac9d1826fb8a25555dbc0c365e627c83413b33ec54
8
+ 8c2d17b8fd807064690e467a504e62488f122816dfe6633c12e7e5c602731c1f
9
+ ea71cc5db9bc57291b342c7c57aca7efb0cdb4d483408e624e4784c46b5e6387
10
+ 03a9459c9d51a456256496cd5c4b869e9a9938554deab6d00d35757690b0e8eb
11
+ 1e3559627ab862dc5c2d484df8de62e5e688be5be6dc153fc6708c1204767c80
12
+ bb59ca780800c5ac88ba97d16df06d655f6378c8e4ed72b0e56035453bb29780
13
+ 56d8c93fa7ac72d3609db5b950dac47da6e93c275f5138b32278ddde0c337ee6
14
+ ea69fa60b4b36a8cf4d474e434ace98326f08e7cc0d3875b49c83c250a596ce6
15
+ 123607bc959c2db77828d2b42f1b05f53a4a8b7e6a74a496f85d23f7ec743cf5
16
+ 6b9aa2ff76e89a810e8ff6371ddf3b72084a03296b75a590b47593d53dec3486
@@ -0,0 +1,16 @@
1
+ 720d2bd3a25198a16f64ac3d4d1f8df7f557e9b35acc9d5581a8f3af82ce60ed
2
+ 79528118740a4d2b64448d079323f4d60b1d388999952971fcb11433bfc7cf13
3
+ f854de5075f0f11bdf7e3169e9b0a4e8cf30debfca55074fb81e6ffd19610290
4
+ ac16db129fca95347325c4a28aceac1b41cca825e817aa15b69bde06305246c4
5
+ 186f694795ff0205ce5394ee94158da39166dbb78013476e10044cabc4ae01e1
6
+ 26f7b3fa2999bb6f0f43e3deec6f31dbdd3d012136e31993c346ba3f9228318d
7
+ 9f6003a457daba22c887e7bacc384096318f9a1b51f7bf54fa73eccf9141e4a1
8
+ 4e067207135567f319705905488a4dea20b4190072cc28749508b521467cfd9c
9
+ 857e5f626be43bd9ee17d291bfdcbc1b9ec806f6a248c906d11dbeb9727fc540
10
+ 9ca0c7711187895faea3d80434b02765bf9734e70d6996c0e85c8bb9cf43997a
11
+ ec3a8d2f8d1d2ad1b6b7df73d5fb0e70cee35e201c05fc601bf2e3646239504f
12
+ 4081ca757b01665e5165768db772d1df533232e207352dc22f7dfc1dbbc5177f
13
+ 2137c93ef01ea7020cd35c8d23c765618a7df1f68182cd2173b2ef78605b46ea
14
+ 0d5f72293e7cfe60d72fd8679b6245ccf9c6a02cf6c3ed22ed8bd4e936cb8b51
15
+ 0bad89c9fb578259d11a9a63e33a387bafbe2e77691b4a978e9ebbf0c1ebe9bd
16
+ 3ed28d1e72df01fcaf3bec7684f4a4e98e9034a90752e3f56129041a24bf90c9
@@ -0,0 +1,16 @@
1
+ 5e8cc51ab1aefd7a4e94d9694e520781035da2599e1bc9f8027bdce7ff38e071
2
+ 42f3d72ba0ce14e7677cc82f032d83e067988de918be1939ec92fb5345eacea0
3
+ 756c2890ee1ad7728a3a37a6152e70395a4175f0875df36c28db779b33a2465d
4
+ 5b7ddc909a5222a3104c735aca5fbb9664eff539881df9758ba57ec29eac190e
5
+ 38c2ad30436156b4097460462f886c2435aff974a890d8202450316ec1a4ccad
6
+ 0adf70c9d2e17a07e3ba5d5de40e2a76b97007da009bf71b07c4f2369e27a340
7
+ 053604687953985c938395d4e7a3ae51c4bbebb89c3fa8c62d77ce5b6fad6a74
8
+ 88ab13123bbfe44bc0feddac059f8c71ecb2ad43972f45b74c90d48cf1a66b45
9
+ 3ff068ee5fcab4e5de968a8effd4d51b051ab90f8998dc5ddaa35539ed31f822
10
+ b875296acfc49ce62e8a26d725a022116c1befc5ad154883d0a8071bf7704a57
11
+ b429b69be4616306dd65c5c4ebdef07a75aa51e9e272fed96175f17419a73e88
12
+ 7a00211dc02e8c6f912d3823a4867841a0728495fa290066c843490e746a44ac
13
+ 222d0a014c9d8a247e9ffd3386c188d402ed21c3037fad84a72d27e0d55d220a
14
+ c78d7bb8b44bd0c4952f2628670820d2063eab056d089aa5623f06c675eac41a
15
+ 16ba9040e748ab4e36a5d66ec59c6a54448cc4e23c75462d2cf10e9443cdb23f
16
+ 9ee130f144ae1964f85756b1af88c7971a909c37b42773fee5fa59beab8ae476
@@ -0,0 +1,16 @@
1
+ d4ea1f50310c6b388dc05225fb144edc2309fcc170578e03d21551d62f6c529b
2
+ d8697d566d84fbe32a6612c9ea7f29d9fbb9580fa94a227985a85127790ab1d5
3
+ 56532a34324d071c42d022594b04541591082c1e01eeb7f3117a9b0b0b597dca
4
+ 0b3a5a6dd4d29e749070632d0bb6efe21545d03a2a83a56be09263c61e7996b3
5
+ dfa9efd413d8b14bfe5ef2266a9bcc7bcb759366d83b52a47757c7eb3b83305a
6
+ 4363131c70131bff160c87d485678a7625ffe84ddf8afe26081f6976bfd9e1de
7
+ 4b08b08f541163376b1b6324e898f6e064895dfb577f27eb6da51cf72fdda1c1
8
+ 2955bdafdb1e25911d18d46b299dc2d1bb758864b12b0f994e8edb7413989152
9
+ 084b742162bd2be14cdec84a1c4d066777258ada62013614d0e35285c299ed20
10
+ 3091bc434a9db50a33d3e40c517fb1eefa206fb4fd6a049541391d80f6d292ac
11
+ 20aaf8f7c29a4dd3395da27a4d389edd3907c6e30808be383bc5b1836e18887b
12
+ 721c980d5dc32db0af11bb834e7e1bebd7f1cf43fbd328cc2c06c71e6a629bd9
13
+ ce0ffb63bc50c92eb33f2e90412820d06ba87ffab6b99b6090a96cf25ec8400c
14
+ c5371b421e9037d5c2f9ec492cf50c624dc2b364a55f3532285d966f777957ed
15
+ 773325da337c54ff631d578b56f961992cb199208a08e02ab0bd7e18acd9cddc
16
+ dfec79db0381280f712129945e2f1f1c1b6d8af4f97363d9786b71a4ec0ba3e7
@@ -0,0 +1,16 @@
1
+ 21f8bb48cae63d93c007ce3c01867c05d98b6f54dcb1271dbfa868928dd908d1
2
+ f0a95b295397d5c5179ffb6db6768c78071468e03f3b28ae050f4ba71c1fb573
3
+ b8b32ffaff720fc59abb293e444668efd2cba500f9718b899992a4bedbda9ca2
4
+ 564c5f8c6ffaeeacc11648f7081e313d220058b7bc4e224f4ae3665de61b3407
5
+ f1b494e6a9e51787e75551e5eab78b65267921dbac0612425cd56e6fb5160541
6
+ d00833db2ead9c2e0959f7d4df3d721eca01a5378c6b5be427427c9ccfddda3c
7
+ 2345e4cde221e719df5a98c5cddcd226c1955eaaa381a790a9ed31bdccc31561
8
+ 9079a1071adae4bb5d92a6b14fcc31f30295843eb05a76d097f83b3e5a91bdfd
9
+ 08c0c7bdeb84b14aa61fa197ee2e1d3ca587380956f9d78e9cb54063328d1db2
10
+ dce9a86dee30cf11516a520e000f962a4285400cfb3534815b7ffaf570021ddb
11
+ 558b83ae432c6d84c3ff41682cabcd009405a6eed44fad326b19b4449f12dc2f
12
+ 994735e737cf223b5c35bf91ddf615f9ede92866861ebf00c5adc99f85e281be
13
+ 3d2fb05abf258f7086df1adaa9b1153dcbd97421afddc1840f236146d4a061d6
14
+ 9045c587beb27ec7e0bdccdb01c322943c6c3f41dc3e64b73c4ce087e6cdbf71
15
+ 2bcde27e4a4c3c353de550dd05221b2739c076b11230fc1e28d7b4ea5781308a
16
+ 1cd0ed94e53172dcad4350801b1bdb2a9eb1906661c803f62adce0b60a040918
@@ -0,0 +1,16 @@
1
+ da047c10deb537fc9054e886d0caca5ddbd92b50e4addb7aeb1671a59672082d
2
+ 77084de68a0d90919280ec6783ab81766f492a88b1389252431f2583c0eefaf5
3
+ e6748050831576d0af305351847a746f4db843bd8b86dd16d376ebffd45af99e
4
+ 33bf4bc21ce7f6325d16495742bb0387a872deb16944ec91d59cf3c2509ffa27
5
+ 7f28f5bb1b8bcaf10419ee1b153ba5f10f45fd6ea033ce73a5e79c22398c6431
6
+ 81de68c34767beb3a569dcfbd6da6299a23048734f9ef6f4b90c8a7f7f796a38
7
+ 4aa0531b7c4ccabf176a62db435d2481a60cce01b8bc2b34c9d93200c105ba01
8
+ 317300d8fe7fc932eddc2e92530979021a429daf17e3506f9e8d2c8317d21c7d
9
+ 0ec23d1c56a22737be5a1f41741b1fa4e6c17964d262b53eb4a87bd8bda46f06
10
+ 3b57ae7bddcc2ea032fdef3584f1784996005517d86852a1a8552694360ae4c3
11
+ adf1a0526704165a4ed38697b40bba6b934fa0c4fcd184554eee9b60dc5e6dc9
12
+ 6a811e36305b8c5f6dd643b3475834eb4c01ef8eda4996d766652479c1064d9c
13
+ 1cf2fc65c25841156b9b40d37137c1d8be316ae656263e5bb80c78a5bd99e50e
14
+ 63298b9ebbd015a76dd4569cfed1c79d300fdec01b642301c05b43299114bd18
15
+ db0778ab7ce627f304206b0cb2b0084ea5de89a7e1076dbe003d311b293d3367
16
+ 1cef389f7e94e5b4fdb49bf34049acbe1409c4542a8a2002c082bcbcf00c2228
@@ -0,0 +1,16 @@
1
+ edc463c935e9c4cf8cff3ad1e825ab90a63019daa233aebd248074556f219e77
2
+ e27cab488b83b915437a6d485b59d6902c5136a1da816515c463bc1dc1574b10
3
+ 7f3df81ebebc9f14998395f6075c55d34cd17f5c8df18b59d036b52e007c5ecf
4
+ 532bce7d2486aec458c94227c0564eebf18b726a67572c98efb812362e539798
5
+ a2dc7c9a3c2500d9b025a3c2f43ec0a540d0f8c9292a31876f3d8dc7a9bf4768
6
+ d1fee3fc1335a8f4e0ffd788ceca90991e0a08a01ab8bc8e59d4e0517a1ed239
7
+ 6ea15f2d28cb31b9d163eb46431ea5600b779eda1843ebc8f640058382b8a96f
8
+ 0007192199c1bd90af17b4fcab5997930e442b2f96a0d274a6c838c07508a2d0
9
+ 4a06289b76f6ea0cf3207864fe727b06e44fffc4584f82c334b4f427471dedbb
10
+ 8aadced49b1d8c565c55892e4fa8134295b41ce24da100d0884b2586f66a5a37
11
+ a241d8c926cbbb2c2edcf216c6fe4fb8c8510ddedf6a21720abf27f448b9acd3
12
+ f788780fd9290f471d03503a75442a53824a73d44c810b39eee7e9cb1d7f6b8b
13
+ 3afe9173afd8541f243070250b07fc9188c30fae04fc6ca1ab10ceb45fafa39a
14
+ cc290a6a790d85371c05a13700e1cf59bec66e2707b94647983d4f0ef8dd8fb6
15
+ 54caa6a8178c01d79a8dda3bf98cb3c9b1a2394e483bfa4451627beb4b79cb5e
16
+ a710a46c3fd1857352c15b9cf65dba498ea8de14e21db09d8a1c9db9ac8591ea
@@ -0,0 +1,16 @@
1
+ e03b7b0d2dd60cd95fe7da8340ef3ebc6ed61921c0eb78a622113fa92b741378
2
+ 8cc77d74e7f266431bd5d938a3f595fddce4ff0bba40c73ad01162ce713c441d
3
+ c4e1e6b47236b80933fa20dd6d4036a72e961bdfee48fe1662a13f7c6d8e4d5b
4
+ 88bd23e9985c981a15bdb5e9046f518df2fba2fc3dd31761e69d987055e48892
5
+ 6a64664ab144a1404bbae297a13d376af4c36bd9b54fda06a18b5f5c1fe50d29
6
+ 5b8a2faf3e8b4c84af5bfbeb00c2f0ff0d460fd85e95064025b41cfafe72a980
7
+ 291ee31de42225c131ac95fdeae55c27e9eddd955465f015f3bcfb7344f6cdbc
8
+ 9175db19869c296308cacd445bbe6cf86143a0f3507b107ffd92762aa315bd3d
9
+ 0db30480b8f6b71562c00be807c0f79beab1cda8b460677e6cc228d69d0fc314
10
+ 9168239614522f5935235834af42fbee5f05ad2211f59942a0a53e0c6629257c
11
+ 3455fa92f90751bb8a42a826e4de9a2c829c24f7e15422b9b78724c2d4d0f46f
12
+ 7bde7a79971d85d2834fcf5856c89360f1958415aa61cd4030db39a66209b5f2
13
+ fb47ac2282808dea1990d681a9e3f60f18b9c792fcc13b28d43d874c5ddf02c1
14
+ 2255496fdcc29fc436edd156922bbd03e5222166e33596d74238fca8a57325a7
15
+ a2a5799e7d22f58030de160af13bab3a8b6f108c224324fec6140f955b99a0e1
16
+ 6653ed7f620088a543073fbacb59b9caf046550a82b8c0bd9e9d5c3275e23b39
@@ -0,0 +1,16 @@
1
+ 9beca0b569e100daa77bc0cae2f8274b8b0b55b035819d8b8d854661ebccb1ba
2
+ c05f336e81ff83a6ef099ea4a7b70dd7d6ea036568cab1304bd91d2d31d0bfe3
3
+ 63032207106e4a1bf4b14c44b8988899af7d0dea5892ac7d5091942c99cbe1c8
4
+ 940c24c7bdf89581810fe923469ce2b29eff0a74451e6e6520d3a4eb2a3bc09a
5
+ d787e660a5660e6875060f1dcae1182fd40f40bf447edd5cf58f91463739bee9
6
+ 16f586fc70ff9b902f67c65b2d4860208d8c1acbdd476b90ca878eb7908f9e6c
7
+ 272a8fe74f5a5a6bc7a7e552b4ab4828a9cdf056024ad7c1713a41795239d81d
8
+ 51d6ed24dd74595ce9156a54fa7f7bd31007a37f4610b1e605d44f07f14edf93
9
+ 0e249567e7a95e75b98e6beee50f19fe9a4050fe2288e94a8bd87bf9efd47710
10
+ fe042e8c3f8c9b5f86d891161bd5809f572f614edbb934a59fffea4c3cabb622
11
+ 20c2bbc4795d97eb816c84f0ad34301d5b30591c8528f11d8d8913d5327d1fad
12
+ 057a718799b4b651922530650f0da7136dcc4dd048647348db3af2bcd1d1fc1a
13
+ 461f64b586fceb204c997223131fa130c1d74195cebdb01232188cf9ff68c4fd
14
+ 64274b236d925d20b6e13942b0aef4446f828d10e36857692ba257a5768ca44d
15
+ cdcf261900d316a5ff7d75bf5660c7e1678bf6cda3334a175274090aac75614c
16
+ 78e96c2fd083dd1f59941db04d9855a970e650b54d4c54b745af5fd323edf5d7
@@ -0,0 +1,16 @@
1
+ 752cf8410dd84a5a1053536f4fe5416009bd4dd6f4db0311bdce88235d336b97
2
+ 2484eb97d5ba977a0b7334aa73e04ca89e6b1d4d73513c94fc19194f23428031
3
+ a3e0e11e7512787b34eb8660072141f187a8771027d32d089a7416411982adce
4
+ b43298b903a704473b94f54efb47f3b6e56a6a269d4564e725dbe47457be7d09
5
+ 906eff7e1d72e3684d34640f6017f16e46ffbee0d1c49f96119d5c83f578a6bf
6
+ c5bd3c9ad6ca34f3a61272efe101560b293a1e653fc2e95b00cb6a036216b393
7
+ 73467c804507f63ddaa29f39de94588de2d0c06c2763a013129f5a662a0d9b5d
8
+ 8fe6f436bbb92066671ab74ba509076be3ee4ca32074962e9eef9c5b34efe7f3
9
+ c0088c630e9b44e0a2c0164320d911be08c157d843d31e540e080fc62f542b34
10
+ c87a737c9f366ef260711a77534a85196e7b16ad6408076411b4e8261b73c0cd
11
+ 0a5549819110866ef00e09e8da148bde5b2163475b048f5021698e95379b65d0
12
+ daca621db335a79aefe95374d2234d28484916990a0b8247e50982a4e5050708
13
+ b67c6cd33e79c8a73acc17072ead0915a25b6a5c42269ef142e90451073776fb
14
+ 2d4e962d84a7917ba699adaa737eb5b4def9608928e2babe4eb0da1cf02d9c33
15
+ 640cf148bafbf8fe3742ee0e1a68b58f2987379488c45a7980660cb1064e4865
16
+ 959a2707348202fd7c20a53d303acd0c4babc35fe39adade5c186b7b31dcffff
@@ -13,6 +13,7 @@ from plexus.common.utils.jsonutils import json_datetime_encoder
13
13
 
14
14
  __all__ = [
15
15
  "compare_postgresql_types",
16
+ "model_name_of",
16
17
  "validate_model_extended",
17
18
  "collect_model_tables",
18
19
  "model_copy_from",
@@ -109,6 +110,13 @@ def compare_postgresql_types(type_a, type_b) -> bool:
109
110
  }
110
111
 
111
112
 
113
+ def model_name_of(model: type[SQLModel], fallback_classname: bool = True) -> str | None:
114
+ table_name = getattr(model, "__tablename__")
115
+ if not table_name:
116
+ return model.__name__ if fallback_classname else None
117
+ return table_name
118
+
119
+
112
120
  def validate_model_extended(model_base: type[SQLModel], model_extended: type[SQLModel]) -> bool:
113
121
  """
114
122
  Validates if ``model_extended`` is an extension of ``model_base`` by checking if all fields in ``model_base``
@@ -363,11 +371,10 @@ def make_record_model_mixin() -> type[RecordModelMixin]:
363
371
  return v
364
372
 
365
373
  @pdt.model_validator(mode="after")
366
- @classmethod
367
- def validate_created_at_updated_at(cls, m: Self) -> Self:
368
- if m.created_at is not None and m.updated_at is not None and m.created_at > m.updated_at:
369
- raise ValueError(f"create time '{m.created_at}' is greater than update time '{m.updated_at}'")
370
- return m
374
+ def validate_created_at_updated_at(self) -> Self:
375
+ if self.created_at is not None and self.updated_at is not None and self.created_at > self.updated_at:
376
+ raise ValueError(f"create time '{self.created_at}' is greater than update time '{self.updated_at}'")
377
+ return self
371
378
 
372
379
  @classmethod
373
380
  def make_index_created_at(cls, index_name: str) -> sa.Index:
@@ -427,11 +434,10 @@ def make_snapshot_model_mixin() -> type[SnapshotModelMixin]:
427
434
  return v
428
435
 
429
436
  @pdt.model_validator(mode="after")
430
- @classmethod
431
- def validate_created_at_expired_at(cls, m: Self) -> Self:
432
- if m.created_at is not None and m.expired_at is not None and m.created_at > m.expired_at:
433
- raise ValueError(f"create time '{m.created_at}' is greater than expire time '{m.expired_at}'")
434
- return m
437
+ def validate_created_at_expired_at(self) -> Self:
438
+ if self.created_at is not None and self.expired_at is not None and self.created_at > self.expired_at:
439
+ raise ValueError(f"create time '{self.created_at}' is greater than expire time '{self.expired_at}'")
440
+ return self
435
441
 
436
442
  @classmethod
437
443
  def make_index_created_at_expired_at(cls, index_name: str) -> sa.Index:
@@ -543,13 +549,12 @@ def make_revision_model_mixin() -> type[RevisionModelMixin]:
543
549
  return v
544
550
 
545
551
  @pdt.model_validator(mode="after")
546
- @classmethod
547
- def validate_created_at_updated_at_expired_at(cls, m: Self) -> Self:
548
- if m.created_at is not None and m.updated_at is not None and m.created_at > m.updated_at:
549
- raise ValueError(f"create time '{m.created_at}' is greater than update time '{m.updated_at}'")
550
- if m.updated_at is not None and m.expired_at is not None and m.updated_at > m.expired_at:
551
- raise ValueError(f"update time '{m.updated_at}' is greater than expire time '{m.expired_at}'")
552
- return m
552
+ def validate_created_at_updated_at_expired_at(self) -> Self:
553
+ if self.created_at is not None and self.updated_at is not None and self.created_at > self.updated_at:
554
+ raise ValueError(f"create time '{self.created_at}' is greater than update time '{self.updated_at}'")
555
+ if self.updated_at is not None and self.expired_at is not None and self.updated_at > self.expired_at:
556
+ raise ValueError(f"update time '{self.updated_at}' is greater than expire time '{self.expired_at}'")
557
+ return self
553
558
 
554
559
  @classmethod
555
560
  def make_index_created_at_updated_at_expired_at(cls, index_name: str) -> sa.Index:
@@ -619,9 +624,9 @@ def make_snapshot_model_trigger[SnapshotModelT: SnapshotModelMixin](engine: sa.E
619
624
  :param engine: SQLAlchemy engine connected to the target database.
620
625
  :param model: The snapshot model class extending `SnapshotModel`.
621
626
  """
622
- table_name = model.__tablename__
627
+ table_name = model_name_of(model, fallback_classname=False)
623
628
  if not table_name:
624
- raise ValueError("missing '__tablename__' attribute")
629
+ raise ValueError("cannot determine table name from model")
625
630
 
626
631
  if not validate_model_extended(SnapshotModel, model):
627
632
  raise ValueError("not an extended model of 'SnapshotModel'")
@@ -688,10 +693,9 @@ def make_revision_model_trigger[RevisionModelT: RevisionModelMixin](engine: sa.E
688
693
  :param engine: SQLAlchemy engine connected to the target database.
689
694
  :param model: The revision model class extending `RevisionModel`.
690
695
  """
691
-
692
- table_name = model.__tablename__
696
+ table_name = model_name_of(model, fallback_classname=False)
693
697
  if not table_name:
694
- raise ValueError("missing '__tablename__' attribute")
698
+ raise ValueError("cannot determine table name from model")
695
699
 
696
700
  if not validate_model_extended(RevisionModel, model):
697
701
  raise ValueError("not an extended model of 'RevisionModel'")
@@ -872,7 +876,7 @@ def db_read_serial_model[SerialModelT: SerialModelMixin](
872
876
  ) -> SerialModelT:
873
877
  db_instance = db.query(model).where(model.sid == sid).one_or_none()
874
878
  if db_instance is None:
875
- raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
879
+ raise sa_exc.NoResultFound(f"'{model_name_of(model)}' of specified sid '{sid}' not found")
876
880
 
877
881
  return db_instance
878
882
 
@@ -900,7 +904,7 @@ def db_update_serial_model[SerialModelT: SerialModelMixin](
900
904
  ) -> SerialModelT:
901
905
  db_instance = db.query(model).where(model.sid == sid).one_or_none()
902
906
  if db_instance is None:
903
- raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
907
+ raise sa_exc.NoResultFound(f"'{model_name_of(model)}' of specified sid '{sid}' not found")
904
908
 
905
909
  db_instance = model_copy_from(db_instance, clone_serial_model_instance(model, instance), exclude_none=True)
906
910
  db_instance = clone_serial_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
@@ -916,7 +920,7 @@ def db_delete_serial_model[SerialModelT: SerialModelMixin](
916
920
  ) -> SerialModelT:
917
921
  db_instance = db.query(model).where(model.sid == sid).one_or_none()
918
922
  if db_instance is None:
919
- raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
923
+ raise sa_exc.NoResultFound(f"'{model_name_of(model)}' of specified sid '{sid}' not found")
920
924
 
921
925
  db.delete(db_instance)
922
926
  db.flush()
@@ -964,7 +968,7 @@ def db_update_record_model[RecordModelT: RecordModelMixin](
964
968
  ) -> RecordModelT:
965
969
  db_instance = db.query(model).where(model.sid == sid).one_or_none()
966
970
  if db_instance is None:
967
- raise sa_exc.NoResultFound(f"'{model}' of specified sid '{sid}' not found")
971
+ raise sa_exc.NoResultFound(f"'{model_name_of(model)}' of specified sid '{sid}' not found")
968
972
 
969
973
  db_instance = model_copy_from(db_instance, clone_record_model_instance(model, instance), exclude_none=True)
970
974
  db_instance.updated_at = updated_at
@@ -1039,7 +1043,7 @@ def db_read_latest_snapshot_model_of_record[SnapshotModelT: SnapshotModelMixin](
1039
1043
  .first()
1040
1044
  )
1041
1045
  if db_instance is None:
1042
- raise sa_exc.NoResultFound(f"'{model}' of specified record_sid '{record_sid}' not found")
1046
+ raise sa_exc.NoResultFound(f"'{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1043
1047
 
1044
1048
  return db_instance
1045
1049
 
@@ -1051,7 +1055,7 @@ def db_read_active_snapshot_model_of_record[SnapshotModelT: SnapshotModelMixin](
1051
1055
  ) -> SnapshotModelT:
1052
1056
  db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
1053
1057
  if db_instance is None:
1054
- raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
1058
+ raise sa_exc.NoResultFound(f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1055
1059
 
1056
1060
  return db_instance
1057
1061
 
@@ -1123,7 +1127,7 @@ def db_update_snapshot_model[SnapshotModelT: SnapshotModelMixin](
1123
1127
  ) -> SnapshotModelT:
1124
1128
  db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
1125
1129
  if db_instance is None:
1126
- raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
1130
+ raise sa_exc.NoResultFound(f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1127
1131
 
1128
1132
  db_instance.expired_at = updated_at
1129
1133
  db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
@@ -1152,7 +1156,7 @@ def db_expire_snapshot_model[SnapshotModelT: SnapshotModelMixin](
1152
1156
  .one_or_none()
1153
1157
  )
1154
1158
  if db_instance is None:
1155
- raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
1159
+ raise sa_exc.NoResultFound(f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1156
1160
 
1157
1161
  db_instance.expired_at = updated_at
1158
1162
  db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
@@ -1169,7 +1173,8 @@ def db_activate_snapshot_model[SnapshotModelT: SnapshotModelMixin](
1169
1173
  ) -> SnapshotModelT:
1170
1174
  db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
1171
1175
  if db_instance is not None:
1172
- raise sa_exc.MultipleResultsFound(f"Active '{model}' of specified record_sid '{record_sid}' already exists")
1176
+ raise sa_exc.MultipleResultsFound(
1177
+ f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' already exists")
1173
1178
 
1174
1179
  db_instance = (
1175
1180
  db
@@ -1179,7 +1184,7 @@ def db_activate_snapshot_model[SnapshotModelT: SnapshotModelMixin](
1179
1184
  .first()
1180
1185
  )
1181
1186
  if db_instance is None:
1182
- raise sa_exc.NoResultFound(f"Expired '{model}' of specified record_sid '{record_sid}' not found")
1187
+ raise sa_exc.NoResultFound(f"Expired '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1183
1188
 
1184
1189
  db_new_instance = clone_snapshot_model_instance(model, db_instance)
1185
1190
  db_new_instance.record_sid = record_sid
@@ -1263,7 +1268,7 @@ def db_read_latest_revision_model_of_record[RevisionModelT: RevisionModelMixin](
1263
1268
  .first()
1264
1269
  )
1265
1270
  if db_instance is None:
1266
- raise sa_exc.NoResultFound(f"'{model}' of specified record_sid '{record_sid}' not found")
1271
+ raise sa_exc.NoResultFound(f"'{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1267
1272
 
1268
1273
  return db_instance
1269
1274
 
@@ -1275,7 +1280,7 @@ def db_read_active_revision_model_of_record[RevisionModelT: RevisionModelMixin](
1275
1280
  ) -> RevisionModelT:
1276
1281
  db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
1277
1282
  if db_instance is None:
1278
- raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
1283
+ raise sa_exc.NoResultFound(f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1279
1284
 
1280
1285
  return db_instance
1281
1286
 
@@ -1347,7 +1352,7 @@ def db_update_revision_model[RevisionModelT: RevisionModelMixin](
1347
1352
  ) -> RevisionModelT:
1348
1353
  db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
1349
1354
  if db_instance is None:
1350
- raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
1355
+ raise sa_exc.NoResultFound(f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1351
1356
 
1352
1357
  db_instance.expired_at = updated_at
1353
1358
  db_instance = clone_revision_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
@@ -1378,7 +1383,7 @@ def db_expire_revision_model[RevisionModelT: RevisionModelMixin](
1378
1383
  .one_or_none()
1379
1384
  )
1380
1385
  if db_instance is None:
1381
- raise sa_exc.NoResultFound(f"Active '{model}' of specified record_sid '{record_sid}' not found")
1386
+ raise sa_exc.NoResultFound(f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1382
1387
 
1383
1388
  db_instance.expired_at = updated_at
1384
1389
  db_instance = clone_revision_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
@@ -1395,7 +1400,8 @@ def db_activate_revision_model[RevisionModelT: RevisionModelMixin](
1395
1400
  ) -> RevisionModelT:
1396
1401
  db_instance = db.query(model).where(model.record_sid == record_sid, model.expired_at.is_(None)).one_or_none()
1397
1402
  if db_instance is not None:
1398
- raise sa_exc.MultipleResultsFound(f"Active '{model}' of specified record_sid '{record_sid}' already exists")
1403
+ raise sa_exc.MultipleResultsFound(
1404
+ f"Active '{model_name_of(model)}' of specified record_sid '{record_sid}' already exists")
1399
1405
 
1400
1406
  db_instance = (
1401
1407
  db
@@ -1405,7 +1411,7 @@ def db_activate_revision_model[RevisionModelT: RevisionModelMixin](
1405
1411
  .first()
1406
1412
  )
1407
1413
  if db_instance is None:
1408
- raise sa_exc.NoResultFound(f"Expired '{model}' of specified record_sid '{record_sid}' not found")
1414
+ raise sa_exc.NoResultFound(f"Expired '{model_name_of(model)}' of specified record_sid '{record_sid}' not found")
1409
1415
 
1410
1416
  db_new_instance = clone_revision_model_instance(model, db_instance)
1411
1417
  db_new_instance.record_sid = record_sid