python-general-be-lib 0.4.2__tar.gz → 0.5.0__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.
- {python_general_be_lib-0.4.2/python_general_be_lib.egg-info → python_general_be_lib-0.5.0}/PKG-INFO +1 -1
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/crud_repository.py +16 -12
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/geometry_repository.py +7 -7
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/handler/__init__.py +1 -0
- python_general_be_lib-0.5.0/general/interface/repository/handler/base_handler.py +23 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/handler/ilike_handler.py +11 -16
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/handler/interval_handler.py +3 -6
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/handler/json_handler.py +1 -3
- python_general_be_lib-0.5.0/general/interface/repository/handler/statement_manager.py +40 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/pyproject.toml +1 -1
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0/python_general_be_lib.egg-info}/PKG-INFO +1 -1
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/python_general_be_lib.egg-info/SOURCES.txt +1 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/setup.py +1 -1
- python_general_be_lib-0.4.2/general/interface/repository/handler/base_handler.py +0 -40
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/LICENSE +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/README.md +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/__init__.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/__init__.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/access_exceptions.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/crud_exceptions.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/exception_interface.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/base/__init__.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/base/base_model.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/base/declarative_base.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/metadata/__init__.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/metadata/crud_metadata.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/metadata/geom_metadata.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/__init__.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/many_to_many_repository.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/view_repository.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/logger.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/paginator_dto.py +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/python_general_be_lib.egg-info/dependency_links.txt +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/python_general_be_lib.egg-info/requires.txt +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/python_general_be_lib.egg-info/top_level.txt +0 -0
- {python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/setup.cfg +0 -0
{python_general_be_lib-0.4.2/python_general_be_lib.egg-info → python_general_be_lib-0.5.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-general-be-lib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
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
|
|
@@ -13,30 +13,34 @@ from sqlalchemy.orm import Session, load_only, defer
|
|
|
13
13
|
from sqlalchemy.sql.functions import count
|
|
14
14
|
|
|
15
15
|
from .handler.base_handler import BaseHandler
|
|
16
|
+
from .handler.statement_manager import StatementManager
|
|
16
17
|
from ...exception.crud_exceptions import HasNoAttributeException, EntityNotFoundException, ServiceUnavailableException, BadRequestException
|
|
17
18
|
from ...interface.base.declarative_base import Base
|
|
18
19
|
from ...paginator_dto import PaginatorResponseModel
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class CrudRepository[Entity: Base | Type[Base]]:
|
|
22
|
-
__slots__ = "model", "entity", "engine", "columns", "
|
|
23
|
+
__slots__ = "model", "entity", "engine", "columns", "stmt_manager", "relationship_attributes"
|
|
23
24
|
|
|
24
25
|
model: Type[BaseModel] | BaseModel
|
|
25
26
|
entity: Entity
|
|
26
27
|
engine: Type[Engine] | Engine
|
|
27
|
-
|
|
28
|
+
stmt_manager: StatementManager | Type[StatementManager]
|
|
28
29
|
|
|
29
30
|
@property
|
|
30
31
|
def open_session(self):
|
|
31
32
|
return Session(self.engine)
|
|
32
33
|
|
|
33
|
-
def __init__(self, entity: Entity, model: Type[BaseModel] | BaseModel, engine: Type[Engine] | Engine,
|
|
34
|
+
def __init__(self, entity: Entity, model: Type[BaseModel] | BaseModel, engine: Type[Engine] | Engine, handlers: list[BaseHandler | Type[BaseHandler]] = None,
|
|
35
|
+
handler_class: Type[BaseHandler] | BaseHandler = None) -> None:
|
|
34
36
|
self.entity = entity
|
|
35
37
|
self.model = model
|
|
36
38
|
self.engine = engine
|
|
37
39
|
self.columns = self.entity.columns()
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
base_handler = handler_class(self.columns) if handler_class else BaseHandler(self.columns)
|
|
42
|
+
|
|
43
|
+
self.stmt_manager = StatementManager(handlers=handlers, base_handler=base_handler)
|
|
40
44
|
|
|
41
45
|
# -------------------------
|
|
42
46
|
|
|
@@ -106,8 +110,8 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
106
110
|
if where is None:
|
|
107
111
|
where = kwhere if kwhere else {}
|
|
108
112
|
stmt = self._select(entity=self.entity, columns=columns, exclude_columns=exclude_columns)
|
|
109
|
-
stmt = self.
|
|
110
|
-
stmt = self.
|
|
113
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
114
|
+
stmt = self.stmt_manager.limit_offset_condition(stmt=stmt, limit=limit)
|
|
111
115
|
return self.execute(session, stmt)
|
|
112
116
|
|
|
113
117
|
def insert(self, session: Session = None, models: list[Type[BaseModel] | BaseModel] = None, returning: bool = True, parsing_model: Type[BaseModel] | BaseModel = None) -> list[Entity]:
|
|
@@ -146,7 +150,7 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
146
150
|
if where is None:
|
|
147
151
|
where = {}
|
|
148
152
|
stmt = update(self.entity)
|
|
149
|
-
stmt = self.
|
|
153
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
150
154
|
|
|
151
155
|
stmt = stmt.values(**kwargs)
|
|
152
156
|
stmt = stmt if not returning else stmt.returning(self.entity)
|
|
@@ -167,7 +171,7 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
167
171
|
if where is None:
|
|
168
172
|
where = kwhere if kwhere else {}
|
|
169
173
|
stmt = delete(self.entity)
|
|
170
|
-
stmt = self.
|
|
174
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
171
175
|
try:
|
|
172
176
|
result = session.execute(stmt)
|
|
173
177
|
except Exception as e:
|
|
@@ -218,7 +222,7 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
218
222
|
if where is None:
|
|
219
223
|
where = kwhere if kwhere else {}
|
|
220
224
|
stmt = select(count(pk))
|
|
221
|
-
stmt = self.
|
|
225
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
222
226
|
result = session.execute(stmt).all()[0]
|
|
223
227
|
return result[0]
|
|
224
228
|
|
|
@@ -244,13 +248,13 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
244
248
|
if where is None:
|
|
245
249
|
where = kwhere if kwhere else {}
|
|
246
250
|
stmt = self._select(entity=self.entity, columns=columns, exclude_columns=exclude_columns)
|
|
247
|
-
stmt = self.
|
|
251
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
248
252
|
|
|
249
253
|
row_numbers = self._preconf_count(session=session, where=stmt.whereclause)
|
|
250
254
|
|
|
251
|
-
stmt = self.
|
|
255
|
+
stmt = self.stmt_manager.limit_offset_condition(stmt=stmt, limit=limit, page=page)
|
|
252
256
|
if order_by:
|
|
253
|
-
stmt = self.
|
|
257
|
+
stmt = self.stmt_manager.order_by_condition(stmt=stmt, order_by=order_by, asc=asc)
|
|
254
258
|
|
|
255
259
|
entities = self.execute(session, stmt)
|
|
256
260
|
return self.parse_pagination(limit=limit, page=page, order_by=order_by, count=row_numbers, asc=asc, data=entities)
|
|
@@ -38,11 +38,11 @@ class GeometryRepository[Entity: Base | Type[Base]](CrudRepository[Entity]):
|
|
|
38
38
|
|
|
39
39
|
intersecting_geom = self._geom_condition(geom=geom, geom_srid=geom_srid, buffer=tolerance)
|
|
40
40
|
|
|
41
|
-
stmt = self.
|
|
42
|
-
stmt = self.
|
|
41
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
42
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, neq=True, **not_where)
|
|
43
43
|
|
|
44
44
|
stmt = stmt.where(self.geom_column.ST_Intersects(intersecting_geom))
|
|
45
|
-
stmt = self.
|
|
45
|
+
stmt = self.stmt_manager.limit_offset_condition(stmt=stmt, limit=limit)
|
|
46
46
|
|
|
47
47
|
return self.execute(session, stmt)
|
|
48
48
|
|
|
@@ -60,14 +60,14 @@ class GeometryRepository[Entity: Base | Type[Base]](CrudRepository[Entity]):
|
|
|
60
60
|
where = {}
|
|
61
61
|
|
|
62
62
|
stmt = self._select(entity=self.entity, columns=columns, exclude_columns=exclude_columns)
|
|
63
|
-
stmt = self.
|
|
63
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
64
64
|
|
|
65
65
|
geom_condition = self._geom_condition(geom=geom, geom_srid=geom_srid, buffer=tolerance)
|
|
66
66
|
geom_condition = self.geom_column.ST_Contains(geom_condition) if not contained else geom_condition.ST_Contains(self.geom_column)
|
|
67
67
|
|
|
68
68
|
stmt = stmt.where(geom_condition)
|
|
69
69
|
|
|
70
|
-
stmt = self.
|
|
70
|
+
stmt = self.stmt_manager.limit_offset_condition(stmt=stmt, limit=limit)
|
|
71
71
|
return self.execute(session, stmt)
|
|
72
72
|
|
|
73
73
|
def nearest(self, geom: WKBElement, session: Session = None, columns: list[str] = None, exclude_columns: list[str] = None, limit: int = 1, where: dict[str, Any] = None, geom_srid: int = 4326,
|
|
@@ -89,9 +89,9 @@ class GeometryRepository[Entity: Base | Type[Base]](CrudRepository[Entity]):
|
|
|
89
89
|
if distance:
|
|
90
90
|
stmt = stmt.add_columns(distance_col)
|
|
91
91
|
|
|
92
|
-
stmt = self.
|
|
92
|
+
stmt = self.stmt_manager.prepare_statement(stmt=stmt, **where)
|
|
93
93
|
stmt = stmt.order_by(literal_column("distance"))
|
|
94
|
-
stmt = self.
|
|
94
|
+
stmt = self.stmt_manager.limit_offset_condition(stmt=stmt, limit=limit)
|
|
95
95
|
|
|
96
96
|
rows = self.execute(session, stmt)
|
|
97
97
|
return rows
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
__all__ = ["BaseHandler"]
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from sqlalchemy import Select, Update, Delete, Column, not_
|
|
6
|
+
from sqlalchemy.sql.base import ReadOnlyColumnCollection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseHandler:
|
|
10
|
+
__slots__ = "columns"
|
|
11
|
+
|
|
12
|
+
def __init__(self, columns: ReadOnlyColumnCollection[str, Column[Any]]):
|
|
13
|
+
self.columns = columns
|
|
14
|
+
|
|
15
|
+
def handle(self, stmt: Select | Update | Delete, neq: bool = False, where: dict[str, Any] = None):
|
|
16
|
+
stmt = stmt.where(*[self._handle(column=self.columns[column], condition=condition, neq=neq) for column, condition in where.items()])
|
|
17
|
+
return stmt
|
|
18
|
+
|
|
19
|
+
def _handle(self, column: Column, condition: Any, neq: bool = False):
|
|
20
|
+
eq_where = column.in_(condition) if isinstance(condition, list) else column == condition if str(column.type) != "ARRAY" else condition == column.any_()
|
|
21
|
+
if neq:
|
|
22
|
+
eq_where = not_(eq_where)
|
|
23
|
+
return eq_where
|
|
@@ -15,24 +15,19 @@ class ILikeHandler(BaseHandler):
|
|
|
15
15
|
|
|
16
16
|
def __init__(self, columns: ReadOnlyColumnCollection[str, Column[Any]], ilike_aliases: list[str] = None, ilike_attributes: list[str] = None):
|
|
17
17
|
self.columns = columns
|
|
18
|
-
self.ilike_aliases = ilike_aliases if not
|
|
19
|
-
self.ilike_attributes = ilike_attributes if not
|
|
18
|
+
self.ilike_aliases = ilike_aliases if ilike_aliases is not None else []
|
|
19
|
+
self.ilike_attributes = ilike_attributes if ilike_attributes is not None else []
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
for ilike_attribute in self.ilike_attributes:
|
|
22
|
+
if ilike_attribute not in self.columns:
|
|
23
|
+
raise ValueError(f"{ilike_attribute} not in columns")
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
stmt = stmt.where(*ilike_conditions)
|
|
27
|
-
return stmt
|
|
28
|
-
|
|
29
|
-
def _ilike_condition(self, condition):
|
|
30
|
-
return or_(*[self.columns[col].ilike(f'%{condition}%') for col in self.ilike_attributes])
|
|
31
|
-
|
|
32
|
-
def retrieve_ilike_values(self, where: dict[str, Any]):
|
|
33
|
-
ilike_values = []
|
|
25
|
+
def handle(self, stmt: Select | Update | Delete, where: dict[str, Any] = None, **kwargs):
|
|
34
26
|
for alias in self.ilike_aliases:
|
|
35
27
|
condition = where.pop(alias, None)
|
|
36
28
|
if condition:
|
|
37
|
-
|
|
38
|
-
return
|
|
29
|
+
stmt = stmt.where(self._handle(alias, condition))
|
|
30
|
+
return stmt
|
|
31
|
+
|
|
32
|
+
def _handle(self, alias: str, condition: str, neq: bool = False):
|
|
33
|
+
return or_(*[self.columns[col].ilike(f'%{condition}%') for col in self.ilike_attributes])
|
|
@@ -14,18 +14,15 @@ class IntervalHandler(BaseHandler):
|
|
|
14
14
|
to_: Any
|
|
15
15
|
inf_is_none: bool
|
|
16
16
|
|
|
17
|
-
def __init__(self, columns: ReadOnlyColumnCollection[str, Column[Any]], from_: Any = None, to_: Any = None, inf_is_none: bool =
|
|
17
|
+
def __init__(self, columns: ReadOnlyColumnCollection[str, Column[Any]], from_: Any = None, to_: Any = None, inf_is_none: bool = False):
|
|
18
18
|
self.columns = columns
|
|
19
19
|
self.from_ = from_
|
|
20
20
|
self.to_ = to_
|
|
21
21
|
self.inf_is_none = inf_is_none
|
|
22
22
|
|
|
23
|
-
def
|
|
24
|
-
|
|
23
|
+
def handle(self, stmt: Select | Update | Delete, where: dict[str, Any] = None, **kwargs):
|
|
25
24
|
from_condition = where.pop(self.from_, None)
|
|
26
|
-
to_condition = where.pop(self.
|
|
27
|
-
|
|
28
|
-
stmt = super().prepare_statement(stmt=stmt, **where)
|
|
25
|
+
to_condition = where.pop(self.to_, None)
|
|
29
26
|
if from_condition:
|
|
30
27
|
stmt = stmt.where(self.columns[self.from_] >= from_condition)
|
|
31
28
|
if to_condition:
|
|
@@ -22,10 +22,8 @@ class JsonHandler(BaseHandler):
|
|
|
22
22
|
except NotImplementedError:
|
|
23
23
|
continue
|
|
24
24
|
|
|
25
|
-
def
|
|
25
|
+
def handle(self, stmt: Select | Update | Delete, where: dict[str, Any] = None, **kwargs):
|
|
26
26
|
json_keys = {key for key in where.keys() if key not in self.columns}
|
|
27
27
|
json_conditions = {key: where.pop(key) for key in json_keys}
|
|
28
|
-
|
|
29
|
-
stmt = super().prepare_statement(stmt=stmt, **where)
|
|
30
28
|
stmt = stmt.where(*[self.columns[self.json_column][key].as_string() == str(value) for key, value in json_conditions.items()])
|
|
31
29
|
return stmt
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
__all__ = ["StatementManager"]
|
|
2
|
+
|
|
3
|
+
from ast import Delete
|
|
4
|
+
from typing import Type
|
|
5
|
+
|
|
6
|
+
from sqlalchemy import Select, Update
|
|
7
|
+
|
|
8
|
+
from general.exception.crud_exceptions import HasNoAttributeException
|
|
9
|
+
from .base_handler import BaseHandler
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StatementManager:
|
|
13
|
+
__slots__ = "_handlers", "_base_handler"
|
|
14
|
+
|
|
15
|
+
def __init__(self, handlers: list[BaseHandler | Type[BaseHandler]] = None, base_handler: BaseHandler = None):
|
|
16
|
+
if not base_handler:
|
|
17
|
+
raise ValueError("StatemantManager: base_handler is not set")
|
|
18
|
+
self._handlers = handlers if handlers else []
|
|
19
|
+
self._base_handler = base_handler
|
|
20
|
+
|
|
21
|
+
def prepare_statement(self, stmt: Select | Update | Delete, neq: bool = False, **where):
|
|
22
|
+
for handler in self._handlers:
|
|
23
|
+
stmt = handler.handle(stmt=stmt, neq=neq, where=where)
|
|
24
|
+
stmt = self._base_handler.handle(stmt=stmt, neq=neq, where=where)
|
|
25
|
+
return stmt
|
|
26
|
+
|
|
27
|
+
def order_by_condition(self, stmt: Select, order_by: str, asc: bool):
|
|
28
|
+
try:
|
|
29
|
+
stmt = stmt.order_by(self._base_handler.columns[order_by].asc()) if asc else stmt.order_by(self._base_handler.columns[order_by].desc())
|
|
30
|
+
except KeyError:
|
|
31
|
+
raise HasNoAttributeException(order_by)
|
|
32
|
+
return stmt
|
|
33
|
+
|
|
34
|
+
def limit_offset_condition(self, stmt: Select, limit: int, page: int = None):
|
|
35
|
+
if limit and limit > 0:
|
|
36
|
+
stmt = stmt.limit(limit)
|
|
37
|
+
if page and page > 0:
|
|
38
|
+
offset = (page - 1) * limit
|
|
39
|
+
stmt = stmt.offset(offset)
|
|
40
|
+
return stmt
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.backends.legacy:build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-general-be-lib"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.0"
|
|
8
8
|
description = "General purpose backend library — SQLAlchemy CRUD/Geometry repositories, FastAPI exceptions, Pydantic base models, logger utilities."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0/python_general_be_lib.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-general-be-lib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
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
|
|
@@ -25,6 +25,7 @@ general/interface/repository/handler/base_handler.py
|
|
|
25
25
|
general/interface/repository/handler/ilike_handler.py
|
|
26
26
|
general/interface/repository/handler/interval_handler.py
|
|
27
27
|
general/interface/repository/handler/json_handler.py
|
|
28
|
+
general/interface/repository/handler/statement_manager.py
|
|
28
29
|
python_general_be_lib.egg-info/PKG-INFO
|
|
29
30
|
python_general_be_lib.egg-info/SOURCES.txt
|
|
30
31
|
python_general_be_lib.egg-info/dependency_links.txt
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
__all__ = ["BaseHandler"]
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from sqlalchemy import Select, Update, Delete, Column, not_
|
|
6
|
-
from sqlalchemy.sql.base import ReadOnlyColumnCollection
|
|
7
|
-
|
|
8
|
-
from general.exception.crud_exceptions import HasNoAttributeException
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class BaseHandler:
|
|
12
|
-
__slots__ = "columns"
|
|
13
|
-
|
|
14
|
-
def __init__(self, columns: ReadOnlyColumnCollection[str, Column[Any]]):
|
|
15
|
-
self.columns = columns
|
|
16
|
-
|
|
17
|
-
def prepare_statement(self, stmt: Select | Update | Delete, neq: bool = False, **where):
|
|
18
|
-
stmt = stmt.where(*[self.handle(column=self.columns[column], condition=condition, neq=neq) for column, condition in where.items()])
|
|
19
|
-
return stmt
|
|
20
|
-
|
|
21
|
-
def order_by_condition(self, stmt: Select, order_by: str, asc: bool):
|
|
22
|
-
try:
|
|
23
|
-
stmt = stmt.order_by(self.columns[order_by].asc()) if asc else stmt.order_by(self.columns[order_by].desc())
|
|
24
|
-
except KeyError:
|
|
25
|
-
raise HasNoAttributeException(order_by)
|
|
26
|
-
return stmt
|
|
27
|
-
|
|
28
|
-
def limit_offset_condition(self, stmt: Select, limit: int, page: int = None):
|
|
29
|
-
if limit and limit > 0:
|
|
30
|
-
stmt = stmt.limit(limit)
|
|
31
|
-
if page and page > 0:
|
|
32
|
-
offset = (page - 1) * limit
|
|
33
|
-
stmt = stmt.offset(offset)
|
|
34
|
-
return stmt
|
|
35
|
-
|
|
36
|
-
def handle(self, column: Column, condition: Any, neq: bool = False):
|
|
37
|
-
eq_where = column.in_(condition) if isinstance(condition, list) else column == condition if str(column.type) != "ARRAY" else condition == column.any_()
|
|
38
|
-
if neq:
|
|
39
|
-
eq_where = not_(eq_where)
|
|
40
|
-
return eq_where
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/access_exceptions.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/crud_exceptions.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/exception/exception_interface.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/base/__init__.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/base/base_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/metadata/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_general_be_lib-0.4.2 → python_general_be_lib-0.5.0}/general/interface/repository/__init__.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
|