python-general-be-lib 0.8.1__tar.gz → 0.8.2__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.8.1/python_general_be_lib.egg-info → python_general_be_lib-0.8.2}/PKG-INFO +1 -1
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/base/declarative_base.py +9 -5
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/crud_repository.py +4 -2
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/pyproject.toml +1 -1
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2/python_general_be_lib.egg-info}/PKG-INFO +1 -1
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/setup.py +1 -1
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_caricamento_parziale.py +48 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/LICENSE +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/README.md +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/__init__.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/__init__.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/access_exceptions.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/crud_exceptions.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/exception_interface.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/base/__init__.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/base/base_model.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/metadata/__init__.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/metadata/crud_metadata.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/metadata/geom_metadata.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/__init__.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/geometry_repository.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/__init__.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/base_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/ilike_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/interval_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/json_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/json_ilike_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/or_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/handler/statement_manager.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/many_to_many_repository.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/repository/view_repository.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/logger.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/paginator_dto.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/python_general_be_lib.egg-info/SOURCES.txt +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/python_general_be_lib.egg-info/dependency_links.txt +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/python_general_be_lib.egg-info/requires.txt +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/python_general_be_lib.egg-info/top_level.txt +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/setup.cfg +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_compiled_cache.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_logger.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_pipeline_handler.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_query_count.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_smoke_crud.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_sql_snapshot.py +0 -0
- {python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_view_repository.py +0 -0
{python_general_be_lib-0.8.1/python_general_be_lib.egg-info → python_general_be_lib-0.8.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-general-be-lib
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
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
|
|
@@ -45,15 +45,19 @@ class Base:
|
|
|
45
45
|
default_values = dict()
|
|
46
46
|
mapper: Mapper = inspect(cls)
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
# ``mapper.columns`` è indicizzato per **nome di attributo** e non forza la
|
|
49
|
+
# configurazione dei mapper: ``column_attrs``/``attrs``/``relationships`` la
|
|
50
|
+
# forzerebbero, e chiamare ``to_pydantic`` a import-time — il pattern
|
|
51
|
+
# documentato — romperebbe le relationship con forward-ref non ancora
|
|
52
|
+
# risolvibili (stessa ragione per cui ``relationship_attributes`` è lazy).
|
|
53
|
+
selected = [(name, column) for name, column in mapper.columns.items()
|
|
54
|
+
if include_only is None or name in include_only]
|
|
49
55
|
|
|
50
56
|
model_name = f"{cls.__name__}Model" if not model_name else model_name
|
|
51
57
|
fields = dict()
|
|
52
|
-
field_values = {
|
|
58
|
+
field_values = {name: None if full_optional else ... for name, _ in selected}
|
|
53
59
|
field_values.update(default_values)
|
|
54
|
-
for
|
|
55
|
-
col = prop.columns[0]
|
|
56
|
-
field_name = prop.key
|
|
60
|
+
for field_name, col in selected:
|
|
57
61
|
if isinstance(col.type, Geometry):
|
|
58
62
|
field_type = Optional[WKBElement] if col.nullable or full_optional else WKBElement
|
|
59
63
|
else:
|
|
@@ -41,7 +41,9 @@ def _reduced_model(entity: Type[Base], columns: frozenset[str]) -> Type[BaseMode
|
|
|
41
41
|
ricostruire il TypeAdapter — mancherebbe il bersaglio a ogni richiesta, e il suo
|
|
42
42
|
`maxsize=None` tratterebbe una voce per classe generata.
|
|
43
43
|
"""
|
|
44
|
-
|
|
44
|
+
# ``mapper.columns`` è indicizzato per nome di attributo e non forza la
|
|
45
|
+
# configurazione dei mapper (a differenza di ``column_attrs``/``attrs``).
|
|
46
|
+
ordinate = [name for name in inspect(entity).columns.keys() if name in columns]
|
|
45
47
|
digest = hashlib.sha1("|".join(ordinate).encode()).hexdigest()[:8]
|
|
46
48
|
return entity.to_pydantic(
|
|
47
49
|
model_name=f"{entity.__name__}_{digest}",
|
|
@@ -131,7 +133,7 @@ class CrudRepository[Entity: Base | Type[Base]]:
|
|
|
131
133
|
|
|
132
134
|
|
|
133
135
|
def _retrieve_parsing_model(self, columns=None, exclude_columns=None):
|
|
134
|
-
selected_columns = set(columns) if columns else set(self.entity.
|
|
136
|
+
selected_columns = set(columns) if columns else set(inspect(self.entity).columns.keys())
|
|
135
137
|
if exclude_columns:
|
|
136
138
|
selected_columns -= set(exclude_columns)
|
|
137
139
|
if columns is None and not exclude_columns:
|
|
@@ -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.8.
|
|
7
|
+
version = "0.8.2"
|
|
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.8.1 → python_general_be_lib-0.8.2/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.8.
|
|
3
|
+
Version: 0.8.2
|
|
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
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/tests/test_caricamento_parziale.py
RENAMED
|
@@ -234,3 +234,51 @@ def test_paging_find_usa_lo_stesso_modello_ridotto(engine: Engine, repo: CrudRep
|
|
|
234
234
|
pagina = repo.paging_find(columns=["nome"], limit=20)
|
|
235
235
|
|
|
236
236
|
assert set(pagina.data[0].model_dump()) == {"nome"}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# ------------------------------------------- configurazione dei mapper a import-time
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def test_to_pydantic_non_forza_la_configurazione_dei_mapper() -> None:
|
|
243
|
+
"""``to_pydantic`` deve funzionare su un'entità con forward-ref non ancora risolvibili.
|
|
244
|
+
|
|
245
|
+
Il pattern documentato è generare i modelli a import-time
|
|
246
|
+
(``UserModel = User.to_pydantic(...)``), quando le entità referenziate per nome
|
|
247
|
+
dalle ``relationship`` possono non essere ancora state importate. Toccare
|
|
248
|
+
``mapper.column_attrs``, ``mapper.attrs`` o ``mapper.relationships`` innesca
|
|
249
|
+
``configure_mappers()`` su **tutto** il registry e fa fallire l'import con::
|
|
250
|
+
|
|
251
|
+
InvalidRequestError: When initializing mapper Mapper[Rel(...)],
|
|
252
|
+
expression 'Azienda' failed to locate a name
|
|
253
|
+
|
|
254
|
+
``mapper.columns`` invece non la forza, ed è già indicizzato per nome di attributo.
|
|
255
|
+
È la stessa ragione per cui ``CrudRepository.relationship_attributes`` è una
|
|
256
|
+
property lazy.
|
|
257
|
+
"""
|
|
258
|
+
from sqlalchemy import ForeignKey
|
|
259
|
+
from sqlalchemy.orm import relationship
|
|
260
|
+
|
|
261
|
+
class RelAziendaUtente(Base):
|
|
262
|
+
__tablename__ = "rel_azienda_utente_probe"
|
|
263
|
+
|
|
264
|
+
id = Column(Integer, primary_key=True)
|
|
265
|
+
id_azienda = Column(Integer, ForeignKey("azienda_probe.id"))
|
|
266
|
+
# riferimento per nome a una classe definita più avanti: irrisolvibile adesso
|
|
267
|
+
azienda = relationship("AziendaProbe")
|
|
268
|
+
|
|
269
|
+
modello = RelAziendaUtente.to_pydantic(full_optional=True)
|
|
270
|
+
assert set(modello.model_fields) == {"id", "id_azienda"}
|
|
271
|
+
|
|
272
|
+
ridotto = RelAziendaUtente.to_pydantic(full_optional=True, include_only=["id_azienda"])
|
|
273
|
+
assert set(ridotto.model_fields) == {"id_azienda"}
|
|
274
|
+
|
|
275
|
+
# la classe mancante arriva dopo: da qui in poi la configurazione può avvenire
|
|
276
|
+
class AziendaProbe(Base):
|
|
277
|
+
__tablename__ = "azienda_probe"
|
|
278
|
+
|
|
279
|
+
id = Column(Integer, primary_key=True)
|
|
280
|
+
|
|
281
|
+
from sqlalchemy.orm import configure_mappers
|
|
282
|
+
|
|
283
|
+
configure_mappers()
|
|
284
|
+
assert RelAziendaUtente.azienda.property.mapper.class_ is AziendaProbe
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/access_exceptions.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/crud_exceptions.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/exception/exception_interface.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/base/__init__.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/base/base_model.py
RENAMED
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/general/interface/metadata/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_general_be_lib-0.8.1 → python_general_be_lib-0.8.2}/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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|