python-general-be-lib 0.11.2__py3-none-any.whl → 0.11.3__py3-none-any.whl
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.
- general/exception/crud_exceptions.py +2 -1
- general/interface/base/__init__.py +50 -3
- general/interface/base/declarative_base.py +2 -1
- general/interface/metadata/__init__.py +53 -7
- general/interface/repository/__init__.py +51 -5
- general/interface/repository/crud_repository.py +8 -1
- general/interface/repository/handler/handler.py +0 -19
- general/interface/repository/handler/statement_manager.py +36 -4
- general/logger.py +11 -3
- {python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/METADATA +2 -1
- {python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/RECORD +14 -14
- {python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/WHEEL +0 -0
- {python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/licenses/LICENSE +0 -0
- {python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/top_level.txt +0 -0
|
@@ -17,7 +17,6 @@ __all__ = [
|
|
|
17
17
|
"InternalServerException",
|
|
18
18
|
]
|
|
19
19
|
|
|
20
|
-
from sqlalchemy.exc import DataError, IntegrityError, NoResultFound, OperationalError
|
|
21
20
|
|
|
22
21
|
from .exception_interface import ExceptionInterface
|
|
23
22
|
|
|
@@ -111,6 +110,8 @@ def raise_http_exception(e: Exception):
|
|
|
111
110
|
BadRequestException: On ``DataError`` or ``IntegrityError``.
|
|
112
111
|
Exception: The original exception, for every other type.
|
|
113
112
|
"""
|
|
113
|
+
from sqlalchemy.exc import DataError, IntegrityError, NoResultFound, OperationalError
|
|
114
|
+
|
|
114
115
|
match e:
|
|
115
116
|
case OperationalError():
|
|
116
117
|
raise ServiceUnavailableException()
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
"""SQLAlchemy declarative base class and preconfigured Pydantic models.
|
|
1
|
+
"""SQLAlchemy declarative base class and preconfigured Pydantic models.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The public symbols are resolved lazily (PEP 562): importing this package does not import
|
|
4
|
+
the modules behind them, so reaching one of them does not pay for the heavier siblings.
|
|
5
|
+
The ``TYPE_CHECKING`` block is what keeps the static types — without it a type checker
|
|
6
|
+
would see every symbol as ``Any``, silently, and the ``py.typed`` marker would promise
|
|
7
|
+
types the consumer does not get.
|
|
8
|
+
"""
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
5
10
|
|
|
6
11
|
__all__ = [
|
|
7
12
|
"Base",
|
|
@@ -10,3 +15,45 @@ __all__ = [
|
|
|
10
15
|
"ExtBaseModel",
|
|
11
16
|
"CamelExtBaseModel",
|
|
12
17
|
]
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING: # i type checker leggono da qui, il runtime no
|
|
20
|
+
from .base_model import CamelExtBaseModel, ExtBaseModel
|
|
21
|
+
from .declarative_base import Base, retrieve_mapper_entity, retrieve_mapper_from_table
|
|
22
|
+
|
|
23
|
+
_MODULES = {
|
|
24
|
+
"Base": ".declarative_base",
|
|
25
|
+
"retrieve_mapper_entity": ".declarative_base",
|
|
26
|
+
"retrieve_mapper_from_table": ".declarative_base",
|
|
27
|
+
"ExtBaseModel": ".base_model",
|
|
28
|
+
"CamelExtBaseModel": ".base_model",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def __getattr__(name: str):
|
|
33
|
+
"""Resolve a public symbol, importing its module on first access.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
name (str): Name of the attribute being read.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Any: The requested symbol.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
AttributeError: If the name is not part of the public surface.
|
|
43
|
+
"""
|
|
44
|
+
module = _MODULES.get(name)
|
|
45
|
+
if module is None:
|
|
46
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
47
|
+
|
|
48
|
+
from importlib import import_module
|
|
49
|
+
|
|
50
|
+
return getattr(import_module(module, __name__), name)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def __dir__() -> list[str]:
|
|
54
|
+
"""List the public surface without importing anything.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
list[str]: The names in ``__all__``.
|
|
58
|
+
"""
|
|
59
|
+
return list(__all__)
|
|
@@ -3,7 +3,6 @@ __all__ = ["Base", "retrieve_mapper_entity", "retrieve_mapper_from_table"]
|
|
|
3
3
|
from functools import lru_cache
|
|
4
4
|
from typing import Optional, Any, Sequence
|
|
5
5
|
|
|
6
|
-
from geoalchemy2 import Geometry, WKBElement
|
|
7
6
|
from pydantic import create_model, ConfigDict
|
|
8
7
|
from sqlalchemy.inspection import inspect
|
|
9
8
|
from sqlalchemy.orm import Mapper, as_declarative
|
|
@@ -54,6 +53,8 @@ class Base:
|
|
|
54
53
|
Returns:
|
|
55
54
|
Type[BaseModel]: Dynamically generated Pydantic class.
|
|
56
55
|
"""
|
|
56
|
+
from geoalchemy2 import Geometry, WKBElement
|
|
57
|
+
|
|
57
58
|
create_model_kwargs.setdefault("__module__", cls.__module__)
|
|
58
59
|
|
|
59
60
|
if "__config__" not in create_model_kwargs.keys() and "__base__" not in create_model_kwargs.keys():
|
|
@@ -1,12 +1,58 @@
|
|
|
1
1
|
"""CRUD and spatial layer over reflected ``Table`` objects, without the ORM.
|
|
2
2
|
|
|
3
|
-
Alternative to the repositories to operate on tables having no ORM model: the schema
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
the SQLAlchemy exceptions onto HTTP exceptions.
|
|
3
|
+
Alternative to the repositories to operate on tables having no ORM model: the schema is
|
|
4
|
+
reflected at runtime and the tables are resolved by name. It goes through the **same**
|
|
5
|
+
handler pipeline as the ORM layer, built per table from the reflected ``Table.c``, and maps
|
|
6
|
+
the SQLAlchemy exceptions onto the same HTTP exceptions.
|
|
7
|
+
|
|
8
|
+
The public symbols are resolved lazily (PEP 562): importing this package does not import
|
|
9
|
+
the modules behind them, so reaching one of them does not pay for the heavier siblings.
|
|
10
|
+
The ``TYPE_CHECKING`` block is what keeps the static types — without it a type checker
|
|
11
|
+
would see every symbol as ``Any``, silently, and the ``py.typed`` marker would promise
|
|
12
|
+
types the consumer does not get.
|
|
7
13
|
"""
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"CrudMetadata",
|
|
18
|
+
"GeomMetadata",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING: # i type checker leggono da qui, il runtime no
|
|
22
|
+
from .crud_metadata import CrudMetadata
|
|
23
|
+
from .geom_metadata import GeomMetadata
|
|
24
|
+
|
|
25
|
+
_MODULES = {
|
|
26
|
+
"CrudMetadata": ".crud_metadata",
|
|
27
|
+
"GeomMetadata": ".geom_metadata",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def __getattr__(name: str):
|
|
32
|
+
"""Resolve a public symbol, importing its module on first access.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
name (str): Name of the attribute being read.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Any: The requested symbol.
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
AttributeError: If the name is not part of the public surface.
|
|
42
|
+
"""
|
|
43
|
+
module = _MODULES.get(name)
|
|
44
|
+
if module is None:
|
|
45
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
46
|
+
|
|
47
|
+
from importlib import import_module
|
|
48
|
+
|
|
49
|
+
return getattr(import_module(module, __name__), name)
|
|
50
|
+
|
|
8
51
|
|
|
9
|
-
|
|
10
|
-
|
|
52
|
+
def __dir__() -> list[str]:
|
|
53
|
+
"""List the public surface without importing anything.
|
|
11
54
|
|
|
12
|
-
|
|
55
|
+
Returns:
|
|
56
|
+
list[str]: The names in ``__all__``.
|
|
57
|
+
"""
|
|
58
|
+
return list(__all__)
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
"""ORM repositories: generic CRUD, spatial, many-to-many and views.
|
|
1
|
+
"""ORM repositories: generic CRUD, spatial, many-to-many and views.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
The public symbols are resolved lazily (PEP 562): importing this package does not import
|
|
4
|
+
the modules behind them, so reaching one of them does not pay for the heavier siblings.
|
|
5
|
+
The ``TYPE_CHECKING`` block is what keeps the static types — without it a type checker
|
|
6
|
+
would see every symbol as ``Any``, silently, and the ``py.typed`` marker would promise
|
|
7
|
+
types the consumer does not get.
|
|
8
|
+
"""
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
7
10
|
|
|
8
11
|
__all__ = [
|
|
9
12
|
"CrudRepository",
|
|
@@ -11,3 +14,46 @@ __all__ = [
|
|
|
11
14
|
"ManyToManyRepository",
|
|
12
15
|
"ViewRepository",
|
|
13
16
|
]
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING: # i type checker leggono da qui, il runtime no
|
|
19
|
+
from .crud_repository import CrudRepository
|
|
20
|
+
from .geometry_repository import GeometryRepository
|
|
21
|
+
from .many_to_many_repository import ManyToManyRepository
|
|
22
|
+
from .view_repository import ViewRepository
|
|
23
|
+
|
|
24
|
+
_MODULES = {
|
|
25
|
+
"CrudRepository": ".crud_repository",
|
|
26
|
+
"GeometryRepository": ".geometry_repository",
|
|
27
|
+
"ManyToManyRepository": ".many_to_many_repository",
|
|
28
|
+
"ViewRepository": ".view_repository",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def __getattr__(name: str):
|
|
33
|
+
"""Resolve a public symbol, importing its module on first access.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
name (str): Name of the attribute being read.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Any: The requested symbol.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
AttributeError: If the name is not part of the public surface.
|
|
43
|
+
"""
|
|
44
|
+
module = _MODULES.get(name)
|
|
45
|
+
if module is None:
|
|
46
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
47
|
+
|
|
48
|
+
from importlib import import_module
|
|
49
|
+
|
|
50
|
+
return getattr(import_module(module, __name__), name)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def __dir__() -> list[str]:
|
|
54
|
+
"""List the public surface without importing anything.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
list[str]: The names in ``__all__``.
|
|
58
|
+
"""
|
|
59
|
+
return list(__all__)
|
|
@@ -147,7 +147,14 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
147
147
|
self.columns = self.entity.columns()
|
|
148
148
|
self._relationship_attributes = None # popolato lazy dalla property relationship_attributes
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
# ``handler_class`` accetta una classe — che si costruisce dalle colonne — oppure
|
|
151
|
+
# un'istanza già pronta: il suggerimento di tipo prometteva entrambe e ne reggeva una
|
|
152
|
+
if handler_class is None:
|
|
153
|
+
base_handler = BaseHandler(self.columns)
|
|
154
|
+
elif isinstance(handler_class, type):
|
|
155
|
+
base_handler = handler_class(self.columns)
|
|
156
|
+
else:
|
|
157
|
+
base_handler = handler_class
|
|
151
158
|
|
|
152
159
|
self.stmt_manager = StatementManager(handlers=handlers, base_handler=base_handler)
|
|
153
160
|
|
|
@@ -32,22 +32,3 @@ class Handler:
|
|
|
32
32
|
the handler claims nothing.
|
|
33
33
|
"""
|
|
34
34
|
return []
|
|
35
|
-
|
|
36
|
-
def handle(self, stmt, neq=False, where=None):
|
|
37
|
-
"""Apply the conditions of this handler alone to a statement.
|
|
38
|
-
|
|
39
|
-
Adapter for the isolated use of a handler, outside the ``StatementManager``
|
|
40
|
-
pipeline: it collects the conditions of ``conditions`` and adds them with a single
|
|
41
|
-
``.where()`` call. Nothing is applied when the handler produces no condition.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
stmt (Select | Update | Delete): Statement to apply the filters to.
|
|
45
|
-
neq (bool): If ``True``, the conditions are negated. Default: ``False``.
|
|
46
|
-
where (dict[str, Any]): Filters. The keys the handler claims are removed
|
|
47
|
-
in-place. Default: ``None``.
|
|
48
|
-
|
|
49
|
-
Returns:
|
|
50
|
-
Select | Update | Delete: Statement with the WHERE conditions applied.
|
|
51
|
-
"""
|
|
52
|
-
conditions = self.conditions(neq=neq, where=where)
|
|
53
|
-
return stmt.where(*conditions) if conditions else stmt
|
|
@@ -5,6 +5,8 @@ from typing import Any, Type
|
|
|
5
5
|
from sqlalchemy import ColumnElement, Delete, Select, Update
|
|
6
6
|
|
|
7
7
|
from general.exception.crud_exceptions import HasNoAttributeException
|
|
8
|
+
from sqlalchemy.sql.base import ReadOnlyColumnCollection
|
|
9
|
+
|
|
8
10
|
from .base_handler import BaseHandler
|
|
9
11
|
|
|
10
12
|
|
|
@@ -27,19 +29,49 @@ class StatementManager:
|
|
|
27
29
|
def __init__(self, handlers: list[BaseHandler | Type[BaseHandler]] = None, base_handler: BaseHandler = None):
|
|
28
30
|
"""Initialize the manager with the handler list and the mandatory base handler.
|
|
29
31
|
|
|
32
|
+
A handler can be given as an instance or as a class: a class is built with the
|
|
33
|
+
columns of the ``base_handler``, which is what every handler needs and the only
|
|
34
|
+
thing some of them need. Building it here is what makes a wrong handler fail at
|
|
35
|
+
construction, where the caller can read the cause, instead of at the first query.
|
|
36
|
+
|
|
30
37
|
Args:
|
|
31
|
-
handlers (list[BaseHandler], optional): Additional handlers
|
|
32
|
-
base handler, such as ``JsonHandler`` or ``ILikeHandler``.
|
|
38
|
+
handlers (list[BaseHandler | Type[BaseHandler]], optional): Additional handlers
|
|
39
|
+
to run before the base handler, such as ``JsonHandler`` or ``ILikeHandler``.
|
|
40
|
+
Each one as an instance or as a class.
|
|
33
41
|
base_handler (BaseHandler): Main handler for the standard filters. Mandatory.
|
|
34
42
|
|
|
35
43
|
Raises:
|
|
36
44
|
ValueError: If ``base_handler`` is not provided.
|
|
45
|
+
TypeError: If a handler class needs more than the columns to be built.
|
|
37
46
|
"""
|
|
38
47
|
if not base_handler:
|
|
39
|
-
raise ValueError("
|
|
40
|
-
self._handlers = handlers if handlers else []
|
|
48
|
+
raise ValueError("StatementManager: base_handler is not set")
|
|
49
|
+
self._handlers = [self._instance_of(handler, base_handler.columns) for handler in handlers] if handlers else []
|
|
41
50
|
self._base_handler = base_handler
|
|
42
51
|
|
|
52
|
+
@staticmethod
|
|
53
|
+
def _instance_of(handler: BaseHandler | Type[BaseHandler], columns: ReadOnlyColumnCollection) -> BaseHandler:
|
|
54
|
+
"""Return the handler itself, building it from the columns when given as a class.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
handler (BaseHandler | Type[BaseHandler]): Handler instance or class.
|
|
58
|
+
columns (ReadOnlyColumnCollection): Columns to build a class with.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
BaseHandler: The handler ready to be run by the pipeline.
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
TypeError: If the class needs more arguments than the columns, with the name of
|
|
65
|
+
the handler and the suggestion to pass an instance.
|
|
66
|
+
"""
|
|
67
|
+
if not isinstance(handler, type):
|
|
68
|
+
return handler
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
return handler(columns)
|
|
72
|
+
except TypeError as e:
|
|
73
|
+
raise TypeError(f"{handler.__name__} needs more than the columns to be built: pass an instance, not the class") from e
|
|
74
|
+
|
|
43
75
|
def conditions(self, neq: bool = False, where: dict[str, Any] = None) -> list[ColumnElement[Any]]:
|
|
44
76
|
"""Collect the conditions of every handler without touching any statement.
|
|
45
77
|
|
general/logger.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import logging.config
|
|
3
|
+
import reprlib
|
|
3
4
|
from functools import wraps
|
|
4
5
|
from time import perf_counter
|
|
5
6
|
|
|
@@ -21,6 +22,11 @@ color = COLOR['BLUE']
|
|
|
21
22
|
end_color = COLOR['ENDC']
|
|
22
23
|
exc_color = COLOR['RED']
|
|
23
24
|
|
|
25
|
+
# Bounded repr of the call arguments for the error record: truncates long strings,
|
|
26
|
+
# collections and object reprs, and falls back to a placeholder when an argument's
|
|
27
|
+
# own ``__repr__`` raises, so that it cannot replace the original exception.
|
|
28
|
+
_args_repr = reprlib.Repr(maxlevel=3, maxtuple=10, maxlist=10, maxdict=10, maxset=10, maxstring=200, maxother=200)
|
|
29
|
+
|
|
24
30
|
LOGGING_CONFIG = {
|
|
25
31
|
"version": 1,
|
|
26
32
|
"disable_existing_loggers": False,
|
|
@@ -100,8 +106,9 @@ def log(func):
|
|
|
100
106
|
``HTTPException`` is propagated as is, any other exception is converted into an
|
|
101
107
|
``InternalServerException``, whose ``detail`` does not carry the original message so
|
|
102
108
|
that internal details never reach the HTTP response body. The call arguments are not
|
|
103
|
-
serialized on the happy path; on error
|
|
104
|
-
|
|
109
|
+
serialized on the happy path; on error their truncated ``repr`` is appended to the
|
|
110
|
+
message, and they are also attached to the record as the ``func_args`` and
|
|
111
|
+
``func_kwargs`` structured fields, available to a JSON handler.
|
|
105
112
|
|
|
106
113
|
The wrapper is **synchronous**: applied to a coroutine function it measures the
|
|
107
114
|
coroutine creation time, not its execution, and does not intercept the exceptions
|
|
@@ -123,7 +130,8 @@ def log(func):
|
|
|
123
130
|
result = func(*args, **kwargs)
|
|
124
131
|
except Exception as e:
|
|
125
132
|
extra = dict(func_args=args, func_kwargs=kwargs)
|
|
126
|
-
|
|
133
|
+
call = f"args={_args_repr.repr(args)} kwargs={_args_repr.repr(kwargs)}"
|
|
134
|
+
logging.exception(f"Exception {exc_color} {func_name} {end_color}: {repr(e)} - {call}", extra=extra)
|
|
127
135
|
raise e.with_traceback(None) if isinstance(e, HTTPException) else InternalServerException()
|
|
128
136
|
else:
|
|
129
137
|
logging.info(f"{color} {func_name} {end_color} completed in {(perf_counter() - start):.3f} seconds")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-general-be-lib
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.3
|
|
4
4
|
Summary: General purpose backend library — SQLAlchemy CRUD/Geometry repositories, FastAPI exceptions, Pydantic base models, logger utilities.
|
|
5
5
|
Author-email: Andrea Di Placido <a.diplacido@arpes.it>, "Arpes S.r.l." <it.admin@arpes.it>
|
|
6
6
|
License: MIT
|
|
@@ -31,6 +31,7 @@ Requires-Dist: testcontainers[postgres]>=4; extra == "dev"
|
|
|
31
31
|
Requires-Dist: psycopg[binary]>=3; extra == "dev"
|
|
32
32
|
Requires-Dist: build; extra == "dev"
|
|
33
33
|
Requires-Dist: twine; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
34
35
|
Dynamic: license-file
|
|
35
36
|
|
|
36
37
|
# python-general-be-lib
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
general/context.py,sha256=ArxisBIbmij72IWKQwBfJBhmAucUGlMnEPRQnYl1A6k,1165
|
|
3
|
-
general/logger.py,sha256=
|
|
3
|
+
general/logger.py,sha256=MnK8ZDA9x4xhX0KcpOxTieosnFIhFVwSa8b52Q4T9tA,5039
|
|
4
4
|
general/paginator_dto.py,sha256=DB2hfcrckuEiHEIORLT4EgCcnX4AYYKGlHRr-l-Q1Cw,3741
|
|
5
5
|
general/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
general/exception/__init__.py,sha256=MZpSDUKeopct7ZqMd1g4XlNS8sM9mmXIlHTIYPOhu9c,849
|
|
7
7
|
general/exception/access_exceptions.py,sha256=tNIBjxM0-5iSOXDc7Il01eb36mEk-POQGVaHhCpG278,744
|
|
8
|
-
general/exception/crud_exceptions.py,sha256=
|
|
8
|
+
general/exception/crud_exceptions.py,sha256=7zA9J8KPlvK9MpHbhFEmFpdGVMcqw7hCyRGSJB4-K7U,4356
|
|
9
9
|
general/exception/exception_interface.py,sha256=k7KreAYMwKPQQghkCissdu3ASZZqrRFWM1lAGzeR8sM,1294
|
|
10
10
|
general/interface/__init__.py,sha256=G11sI1Oxtb-Z_-ORAuKS_Kkdwopt1uXmEXYtZEJYiLs,445
|
|
11
|
-
general/interface/base/__init__.py,sha256=
|
|
11
|
+
general/interface/base/__init__.py,sha256=wRKbvb8lF33_2iG100mEQXz1tEkh9BF5bPcIi7ri_Rk,1801
|
|
12
12
|
general/interface/base/base_model.py,sha256=aIzrRZVUytmbgmEH1bya29rVFOm-Njinn_JXkgkBrr8,2575
|
|
13
|
-
general/interface/base/declarative_base.py,sha256=
|
|
14
|
-
general/interface/metadata/__init__.py,sha256=
|
|
13
|
+
general/interface/base/declarative_base.py,sha256=J-q6nJIdYixFk9tgWjmGVII2cHeOazf0e4snaO_rHhI,9302
|
|
14
|
+
general/interface/metadata/__init__.py,sha256=CawnfGK7WcJmtqi9CjEjBqCyX_vuHFK-Td1orXTH__U,1849
|
|
15
15
|
general/interface/metadata/crud_metadata.py,sha256=SfV2__zgkTTeX1opLHDMRIeyB1DKiObr7pGOHkGVFlo,48120
|
|
16
16
|
general/interface/metadata/geom_metadata.py,sha256=xWNZnWhN_Om91pcqSsURKi5EUYNZh444zDqMwoOpq84,15508
|
|
17
17
|
general/interface/mixin/__init__.py,sha256=M5-e6T_R63Utwh3_WcmoE3wanwIZjNjbgLYrrFlSpTA,659
|
|
18
18
|
general/interface/mixin/audit_mixin.py,sha256=N2JDD9JxXDMeBqu0yAlhVWFOK3EeUA2b215hPvXytUU,1421
|
|
19
19
|
general/interface/mixin/softdelete_mixin.py,sha256=526luzM4DBCorcq99kZ6BYqtQKKJCpnxX9rSEigfyIU,2148
|
|
20
20
|
general/interface/mixin/timestamp_mixin.py,sha256=wmcIx2Y8jgVqg9A-1E61BvkcKCo52ZjKNHeKfXJmUl0,2220
|
|
21
|
-
general/interface/repository/__init__.py,sha256=
|
|
22
|
-
general/interface/repository/crud_repository.py,sha256=
|
|
21
|
+
general/interface/repository/__init__.py,sha256=QQD6okLfRozC0uOZPGrwOUDKJyZTgpObvwJ3OOSJdbM,1813
|
|
22
|
+
general/interface/repository/crud_repository.py,sha256=Hr7APBsN1uFqEfM78ZSIcgheg4ilvND4OMc7TBNOlcw,55962
|
|
23
23
|
general/interface/repository/geometry_repository.py,sha256=Fmv0qhfqumnU5fiETMMAmiB0UyG43b19jlPXQ8cJ9CU,11289
|
|
24
24
|
general/interface/repository/many_to_many_repository.py,sha256=KRJ2SMUGDYNoGV-ea541wlWg0FW4NQ_Ry85aJBarmC8,11183
|
|
25
25
|
general/interface/repository/view_repository.py,sha256=wxDGw7kenuVrDd9nfh7-omw2m9Jex5WzF_lhEiqPoA0,7902
|
|
26
26
|
general/interface/repository/handler/__init__.py,sha256=uhtGETCY-s9lJsn919u0e7XnPsGjBjxjjtJFnn5XrV4,686
|
|
27
27
|
general/interface/repository/handler/base_handler.py,sha256=aVT6s60rsdZUqQlKWlUyuiGgVxzFLJCb7uztn859sL4,3363
|
|
28
|
-
general/interface/repository/handler/handler.py,sha256=
|
|
28
|
+
general/interface/repository/handler/handler.py,sha256=tzoJXjf43bgdczwSbcvVeUtt6xZU6ZSkVgfMFwuu2eg,1538
|
|
29
29
|
general/interface/repository/handler/ilike_handler.py,sha256=OM3klDlx7ixqWF7kklWj8kbgVY_5ZNitcQ0usGnQP_0,4015
|
|
30
30
|
general/interface/repository/handler/interval_handler.py,sha256=4TtEcpzUFZeyB-yitib5Kpe3U67aS07uye4K7jXrtG4,5517
|
|
31
31
|
general/interface/repository/handler/json_handler.py,sha256=f_nGemsxTPJ3W0xkU99sCFA0EVo1xa8p803NyjcGJT4,4414
|
|
32
32
|
general/interface/repository/handler/json_ilike_handler.py,sha256=icfA4dO8E_W_KUEG5HB1nLVI1jfjxzkG8ZJ-IaCd4kY,3530
|
|
33
33
|
general/interface/repository/handler/or_handler.py,sha256=UOjIh77H4y-x434YGLYRfVIXKnod1M5XPiMf71V2JTg,3137
|
|
34
34
|
general/interface/repository/handler/soft_delete_handler.py,sha256=1WD1n6q5plyJ0RDniJcEwNlic1WJqXvSlCj99VLc_3A,4100
|
|
35
|
-
general/interface/repository/handler/statement_manager.py,sha256=
|
|
35
|
+
general/interface/repository/handler/statement_manager.py,sha256=JSj6K-iQJ06kLdsMTOqK62cIvR87ioOA1LmLTGpqrB0,8205
|
|
36
36
|
general/utils/__init__.py,sha256=_SPe88reIZ0JxwK7mp-u_p-9c4hCcZ-daUihi0gymNk,103
|
|
37
37
|
general/utils/consts.py,sha256=nE75Ud7sVuDw9K_xmIJNjL_5f_BVJmwGNPGFYc26H3Y,264
|
|
38
|
-
python_general_be_lib-0.11.
|
|
39
|
-
python_general_be_lib-0.11.
|
|
40
|
-
python_general_be_lib-0.11.
|
|
41
|
-
python_general_be_lib-0.11.
|
|
42
|
-
python_general_be_lib-0.11.
|
|
38
|
+
python_general_be_lib-0.11.3.dist-info/licenses/LICENSE,sha256=iUaO1XZyB9P3Tmog0OILuTisP6vXGe3QKz-4yRTxOFk,1069
|
|
39
|
+
python_general_be_lib-0.11.3.dist-info/METADATA,sha256=kXWrKc_wD4H6khCeqnluMKmFoD-8AopOF8m3RXISA1s,3452
|
|
40
|
+
python_general_be_lib-0.11.3.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
41
|
+
python_general_be_lib-0.11.3.dist-info/top_level.txt,sha256=tTZePW8_CNUqSgKFd2SEH72ZbnhS0OYjRsgcv0ikSFY,8
|
|
42
|
+
python_general_be_lib-0.11.3.dist-info/RECORD,,
|
|
File without changes
|
{python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{python_general_be_lib-0.11.2.dist-info → python_general_be_lib-0.11.3.dist-info}/top_level.txt
RENAMED
|
File without changes
|