lush-sqlalchemyx 0.3.2__tar.gz → 0.4.1__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.
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/PKG-INFO +2 -2
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/pyproject.toml +2 -2
- lush_sqlalchemyx-0.4.1/src/lush_sqlalchemyx/__init__.py +19 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/__init__.py +10 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_async.py +11 -3
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_common.py +108 -8
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_sync.py +11 -3
- lush_sqlalchemyx-0.3.2/src/lush_sqlalchemyx/shortcuts/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/README.md +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/_compat.py +0 -0
- {lush_sqlalchemyx-0.3.2/src/lush_sqlalchemyx → lush_sqlalchemyx-0.4.1/src/lush_sqlalchemyx/base}/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_pagination.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_repository.py +0 -0
- {lush_sqlalchemyx-0.3.2/src/lush_sqlalchemyx/base → lush_sqlalchemyx-0.4.1/src/lush_sqlalchemyx/integrations}/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/integrations/fastapi/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/integrations/fastapi/depends/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/integrations/flask/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/integrations/flask/ext.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/manager.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/mapper.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/sync_manager.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/sync_mapper.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/py.typed +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/same_impl_just_warn_wrapper.py +0 -0
- {lush_sqlalchemyx-0.3.2/src/lush_sqlalchemyx/integrations → lush_sqlalchemyx-0.4.1/src/lush_sqlalchemyx/shortcuts}/__init__.py +0 -0
- {lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/shortcuts/meta.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: lush-sqlalchemyx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: SQLAlchemy helpers (DAL) and async MySQL managers, with some web frameworks integrations
|
|
5
5
|
Author: straydragon
|
|
6
6
|
Author-email: straydragon <straydragonl@foxmail.com>
|
|
@@ -12,7 +12,7 @@ Requires-Dist: pydantic>=2.3.0,<3.0.0
|
|
|
12
12
|
Requires-Dist: typing-extensions>=4.12.2
|
|
13
13
|
Requires-Dist: lush-pydanticx>=0.1.0
|
|
14
14
|
Requires-Dist: lush-stdx>=0.1.0
|
|
15
|
-
Requires-Dist: lush-dal-protocol>=0.
|
|
15
|
+
Requires-Dist: lush-dal-protocol>=0.2.2
|
|
16
16
|
Requires-Dist: sqlalchemy[asyncio]>=2.0.43 ; extra == 'asyncio'
|
|
17
17
|
Requires-Dist: flask-sqlalchemy>=3.1.1 ; extra == 'flask'
|
|
18
18
|
Requires-Python: >=3.10
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lush-sqlalchemyx"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = "SQLAlchemy helpers (DAL) and async MySQL managers, with some web frameworks integrations"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -16,7 +16,7 @@ dependencies = [
|
|
|
16
16
|
"typing-extensions>=4.12.2",
|
|
17
17
|
"lush-pydanticx>=0.1.0",
|
|
18
18
|
"lush-stdx>=0.1.0",
|
|
19
|
-
"lush-dal-protocol>=0.
|
|
19
|
+
"lush-dal-protocol>=0.2.2",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[project.optional-dependencies]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""lush-sqlalchemyx — SQLAlchemy DAL 实现 + async/sync MySQL manager + 框架集成.
|
|
2
|
+
|
|
3
|
+
导入本包时会自动注册软删除 Session 事件监听器.
|
|
4
|
+
如需显式管理钩子生命周期, 参见 :func:`register_soft_delete_hooks` 等.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from lush_sqlalchemyx.base.dal import (
|
|
8
|
+
is_soft_delete_hooks_registered,
|
|
9
|
+
register_soft_delete_hooks,
|
|
10
|
+
setup_dal_hooks,
|
|
11
|
+
unregister_soft_delete_hooks,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = (
|
|
15
|
+
"is_soft_delete_hooks_registered",
|
|
16
|
+
"register_soft_delete_hooks",
|
|
17
|
+
"setup_dal_hooks",
|
|
18
|
+
"unregister_soft_delete_hooks",
|
|
19
|
+
)
|
|
@@ -43,6 +43,7 @@ from ._common import (
|
|
|
43
43
|
CUModelT,
|
|
44
44
|
DBRetryableError,
|
|
45
45
|
DTOModelT,
|
|
46
|
+
FieldIsDeleteSoftDeleteTableMixin,
|
|
46
47
|
FieldMixin,
|
|
47
48
|
ReadOnlyMixin,
|
|
48
49
|
RetryConfig,
|
|
@@ -52,6 +53,10 @@ from ._common import (
|
|
|
52
53
|
StdBaseDTO,
|
|
53
54
|
escape_like,
|
|
54
55
|
filtered_in_sql_values,
|
|
56
|
+
is_soft_delete_hooks_registered,
|
|
57
|
+
register_soft_delete_hooks,
|
|
58
|
+
setup_dal_hooks,
|
|
59
|
+
unregister_soft_delete_hooks,
|
|
55
60
|
)
|
|
56
61
|
|
|
57
62
|
# Event listener references — accessed by tests via getattr(module, name).
|
|
@@ -102,10 +107,15 @@ __all__ = (
|
|
|
102
107
|
"RetryConfig",
|
|
103
108
|
"SQLATableT",
|
|
104
109
|
"SoftDeleteTableMixin",
|
|
110
|
+
"FieldIsDeleteSoftDeleteTableMixin",
|
|
105
111
|
"StdBaseCU",
|
|
106
112
|
"StdBaseDTO",
|
|
107
113
|
"escape_like",
|
|
108
114
|
"filtered_in_sql_values",
|
|
115
|
+
"is_soft_delete_hooks_registered",
|
|
116
|
+
"register_soft_delete_hooks",
|
|
117
|
+
"setup_dal_hooks",
|
|
118
|
+
"unregister_soft_delete_hooks",
|
|
109
119
|
# async
|
|
110
120
|
"AsyncBaseDAL",
|
|
111
121
|
"AsyncRawDAL",
|
|
@@ -31,6 +31,7 @@ from ._common import (
|
|
|
31
31
|
CUModelT,
|
|
32
32
|
DBRetryableError,
|
|
33
33
|
DTOModelT,
|
|
34
|
+
FieldIsDeleteSoftDeleteTableMixin,
|
|
34
35
|
ReadOnlyMixin,
|
|
35
36
|
RetryConfig,
|
|
36
37
|
SoftDeleteTableMixin,
|
|
@@ -142,7 +143,7 @@ class ReadOnlyBasicAsyncBaseTable(AsyncSqlATableBase, ReadOnlyMixin):
|
|
|
142
143
|
__abstract__ = True
|
|
143
144
|
|
|
144
145
|
|
|
145
|
-
class StdAsyncBaseTable(BasicAsyncBaseTable,
|
|
146
|
+
class StdAsyncBaseTable(BasicAsyncBaseTable, FieldIsDeleteSoftDeleteTableMixin):
|
|
146
147
|
"""标准异步表类: 包含 id/时间戳/操作人/软删除等标准字段.
|
|
147
148
|
|
|
148
149
|
.. deprecated::
|
|
@@ -333,7 +334,10 @@ class AsyncReadDAL(
|
|
|
333
334
|
session: AsyncSession,
|
|
334
335
|
entity_id: int,
|
|
335
336
|
) -> AsyncSQLATableT | None:
|
|
336
|
-
|
|
337
|
+
entity = await session.get(cls._Table, entity_id)
|
|
338
|
+
if entity is not None and isinstance(entity, SoftDeleteTableMixin) and entity.is_soft_deleted:
|
|
339
|
+
return None
|
|
340
|
+
return entity
|
|
337
341
|
|
|
338
342
|
@classmethod
|
|
339
343
|
async def batch_get_field__entity(
|
|
@@ -407,6 +411,8 @@ class AsyncReadDAL(
|
|
|
407
411
|
) -> DTOModelT | None:
|
|
408
412
|
entity = await session.get(cls._Table, entity_id)
|
|
409
413
|
if entity:
|
|
414
|
+
if isinstance(entity, SoftDeleteTableMixin) and entity.is_soft_deleted:
|
|
415
|
+
return None
|
|
410
416
|
if need_refresh:
|
|
411
417
|
await session.refresh(entity)
|
|
412
418
|
return cls._DTO.model_validate(entity)
|
|
@@ -428,7 +434,9 @@ class AsyncReadDAL(
|
|
|
428
434
|
@classmethod
|
|
429
435
|
async def exists(cls, session: AsyncSession, entity_id: int) -> bool:
|
|
430
436
|
entity = await session.get(cls._Table, entity_id)
|
|
431
|
-
|
|
437
|
+
if entity is None:
|
|
438
|
+
return False
|
|
439
|
+
return not (isinstance(entity, SoftDeleteTableMixin) and entity.is_soft_deleted)
|
|
432
440
|
|
|
433
441
|
@classmethod
|
|
434
442
|
async def get_by_id_for_update(
|
|
@@ -212,15 +212,51 @@ class StdBaseDTO(BaseDTO[CUModelT]):
|
|
|
212
212
|
|
|
213
213
|
|
|
214
214
|
class SoftDeleteTableMixin:
|
|
215
|
-
"""
|
|
215
|
+
"""软删除表标记混入类 — 不强制任何列名或类型.
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
子类必须提供软删除列并覆写 ``is_soft_deleted`` property.
|
|
218
|
+
快捷方式: 继承 ``FieldIsDeleteSoftDeleteTableMixin`` 获得标准 ``is_delete`` 列.
|
|
219
|
+
|
|
220
|
+
自定义示例::
|
|
221
|
+
|
|
222
|
+
class MyTable(Base, SoftDeleteTableMixin):
|
|
223
|
+
__soft_delete_column__ = "deleted_at"
|
|
224
|
+
|
|
225
|
+
deleted_at: Mapped[datetime | None] = mapped_column(sa.DateTime, nullable=True, default=None)
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def is_soft_deleted(self) -> bool:
|
|
229
|
+
return self.deleted_at is not None
|
|
218
230
|
|
|
219
|
-
|
|
220
|
-
|
|
231
|
+
def soft_delete(self) -> None:
|
|
232
|
+
from datetime import datetime, timezone
|
|
221
233
|
|
|
222
|
-
|
|
223
|
-
|
|
234
|
+
self.deleted_at = datetime.now(timezone.utc)
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
__soft_delete_column__: ClassVar[str] = "is_delete"
|
|
238
|
+
|
|
239
|
+
def soft_delete(self) -> None:
|
|
240
|
+
"""标记为软删除."""
|
|
241
|
+
setattr(self, self.__soft_delete_column__, 1)
|
|
242
|
+
|
|
243
|
+
def soft_undelete(self) -> None:
|
|
244
|
+
"""恢复软删除."""
|
|
245
|
+
setattr(self, self.__soft_delete_column__, 0)
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def is_soft_deleted(self) -> bool:
|
|
249
|
+
"""实体是否已被软删除(默认检查 ``is_delete != 0``,子类可覆写)."""
|
|
250
|
+
return bool(getattr(self, self.__soft_delete_column__))
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class FieldIsDeleteSoftDeleteTableMixin(SoftDeleteTableMixin):
|
|
254
|
+
"""标准软删除混入类 — 提供 ``is_delete: Mapped[int]`` 列.
|
|
255
|
+
|
|
256
|
+
等价旧版 ``SoftDeleteTableMixin``,仅需 rename.
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
is_delete: Mapped[int] = mapped_column(sa.Integer, default=0, comment="逻辑删除")
|
|
224
260
|
|
|
225
261
|
|
|
226
262
|
class ReadOnlyMixin:
|
|
@@ -267,6 +303,65 @@ class FieldMixin:
|
|
|
267
303
|
return
|
|
268
304
|
|
|
269
305
|
|
|
306
|
+
# ---------------------------------------------------------------------------
|
|
307
|
+
# Soft-delete hook management API (explicit register/unregister/check)
|
|
308
|
+
# ---------------------------------------------------------------------------
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def register_soft_delete_hooks() -> None:
|
|
312
|
+
"""显式注册软删除 Session 事件监听器(幂等)。
|
|
313
|
+
|
|
314
|
+
在以下场景需要显式调用:
|
|
315
|
+
- 多进程 worker 子进程(import 可能未触发)
|
|
316
|
+
- 测试中自建 Session、未走应用启动链
|
|
317
|
+
- FastAPI lifespan / Flask app factory 显式初始化
|
|
318
|
+
"""
|
|
319
|
+
if not sa_event.contains(SyncSession, "before_flush", __receive_before_flush):
|
|
320
|
+
sa_event.listen(SyncSession, "before_flush", __receive_before_flush, insert=True)
|
|
321
|
+
if not sa_event.contains(SyncSession, "do_orm_execute", __add_filtering_criteria):
|
|
322
|
+
sa_event.listen(SyncSession, "do_orm_execute", __add_filtering_criteria, insert=True)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def unregister_soft_delete_hooks() -> None:
|
|
326
|
+
"""注销软删除 Session 事件监听器(幂等)。"""
|
|
327
|
+
if sa_event.contains(SyncSession, "before_flush", __receive_before_flush):
|
|
328
|
+
sa_event.remove(SyncSession, "before_flush", __receive_before_flush)
|
|
329
|
+
if sa_event.contains(SyncSession, "do_orm_execute", __add_filtering_criteria):
|
|
330
|
+
sa_event.remove(SyncSession, "do_orm_execute", __add_filtering_criteria)
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def is_soft_delete_hooks_registered() -> bool:
|
|
334
|
+
"""检查软删除钩子是否已注册。"""
|
|
335
|
+
return sa_event.contains(SyncSession, "before_flush", __receive_before_flush) and sa_event.contains(
|
|
336
|
+
SyncSession, "do_orm_execute", __add_filtering_criteria
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def setup_dal_hooks() -> None:
|
|
341
|
+
"""注册所有必要的 Session 事件监听器(幂等)。
|
|
342
|
+
|
|
343
|
+
在应用生命周期开始时**调用一次**即可,无需关注具体注册了哪些钩子。
|
|
344
|
+
涵盖:软删除拦截、软删除查询过滤、只读保护。
|
|
345
|
+
|
|
346
|
+
FastAPI 示例::
|
|
347
|
+
|
|
348
|
+
@asynccontextmanager
|
|
349
|
+
async def lifespan(app):
|
|
350
|
+
setup_dal_hooks()
|
|
351
|
+
yield
|
|
352
|
+
|
|
353
|
+
Flask 示例::
|
|
354
|
+
|
|
355
|
+
def create_app():
|
|
356
|
+
app = Flask(__name__)
|
|
357
|
+
setup_dal_hooks()
|
|
358
|
+
return app
|
|
359
|
+
"""
|
|
360
|
+
register_soft_delete_hooks()
|
|
361
|
+
if not sa_event.contains(SyncSession, "before_flush", __prevent_readonly_write):
|
|
362
|
+
sa_event.listen(SyncSession, "before_flush", __prevent_readonly_write, insert=True)
|
|
363
|
+
|
|
364
|
+
|
|
270
365
|
# ---------------------------------------------------------------------------
|
|
271
366
|
# Session event listeners (registered on SyncSession — works for both sync
|
|
272
367
|
# and async since AsyncSession delegates to a SyncSession internally)
|
|
@@ -277,7 +372,7 @@ class FieldMixin:
|
|
|
277
372
|
def __receive_before_flush(session: SyncSession, flush_context: Any, instances: Any) -> None: # noqa: ARG001 # pyright: ignore[reportUnusedFunction, reportUnusedParameter]
|
|
278
373
|
for instance in session.deleted:
|
|
279
374
|
if isinstance(instance, SoftDeleteTableMixin):
|
|
280
|
-
instance.
|
|
375
|
+
instance.soft_delete()
|
|
281
376
|
session.add(instance)
|
|
282
377
|
|
|
283
378
|
|
|
@@ -292,7 +387,7 @@ def __add_filtering_criteria(execute_state: ORMExecuteState) -> None: # pyright
|
|
|
292
387
|
execute_state.statement = execute_state.statement.options(
|
|
293
388
|
with_loader_criteria(
|
|
294
389
|
SoftDeleteTableMixin,
|
|
295
|
-
lambda
|
|
390
|
+
lambda cls: getattr(cls, getattr(cls, "__soft_delete_column__", "is_delete"), sa.null()) == 0,
|
|
296
391
|
include_aliases=True,
|
|
297
392
|
)
|
|
298
393
|
)
|
|
@@ -352,6 +447,11 @@ __all__ = (
|
|
|
352
447
|
"T",
|
|
353
448
|
"V",
|
|
354
449
|
"_ensure_strict_fields",
|
|
450
|
+
"FieldIsDeleteSoftDeleteTableMixin",
|
|
355
451
|
"escape_like",
|
|
356
452
|
"filtered_in_sql_values",
|
|
453
|
+
"is_soft_delete_hooks_registered",
|
|
454
|
+
"register_soft_delete_hooks",
|
|
455
|
+
"setup_dal_hooks",
|
|
456
|
+
"unregister_soft_delete_hooks",
|
|
357
457
|
)
|
|
@@ -28,6 +28,7 @@ from ._common import (
|
|
|
28
28
|
CUModelT,
|
|
29
29
|
DBRetryableError,
|
|
30
30
|
DTOModelT,
|
|
31
|
+
FieldIsDeleteSoftDeleteTableMixin,
|
|
31
32
|
ReadOnlyMixin,
|
|
32
33
|
RetryConfig,
|
|
33
34
|
SoftDeleteTableMixin,
|
|
@@ -136,7 +137,7 @@ class ReadOnlySyncBaseTable(SyncSqlATableBase, ReadOnlyMixin):
|
|
|
136
137
|
__abstract__ = True
|
|
137
138
|
|
|
138
139
|
|
|
139
|
-
class StdSyncBaseTable(BasicSyncBaseTable,
|
|
140
|
+
class StdSyncBaseTable(BasicSyncBaseTable, FieldIsDeleteSoftDeleteTableMixin):
|
|
140
141
|
"""标准同步表类: 包含 id/时间戳/操作人/软删除等标准字段.
|
|
141
142
|
|
|
142
143
|
.. deprecated::
|
|
@@ -326,7 +327,10 @@ class SyncReadDAL(
|
|
|
326
327
|
session: Session,
|
|
327
328
|
entity_id: int,
|
|
328
329
|
) -> SyncSQLATableT | None:
|
|
329
|
-
|
|
330
|
+
entity = session.get(cls._Table, entity_id)
|
|
331
|
+
if entity is not None and isinstance(entity, SoftDeleteTableMixin) and entity.is_soft_deleted:
|
|
332
|
+
return None
|
|
333
|
+
return entity
|
|
330
334
|
|
|
331
335
|
@classmethod
|
|
332
336
|
def batch_get_field__entity(
|
|
@@ -398,6 +402,8 @@ class SyncReadDAL(
|
|
|
398
402
|
) -> DTOModelT | None:
|
|
399
403
|
entity = session.get(cls._Table, entity_id)
|
|
400
404
|
if entity:
|
|
405
|
+
if isinstance(entity, SoftDeleteTableMixin) and entity.is_soft_deleted:
|
|
406
|
+
return None
|
|
401
407
|
if need_refresh:
|
|
402
408
|
session.refresh(entity)
|
|
403
409
|
return cls._DTO.model_validate(entity)
|
|
@@ -419,7 +425,9 @@ class SyncReadDAL(
|
|
|
419
425
|
@classmethod
|
|
420
426
|
def exists(cls, session: Session, entity_id: int) -> bool:
|
|
421
427
|
entity = session.get(cls._Table, entity_id)
|
|
422
|
-
|
|
428
|
+
if entity is None:
|
|
429
|
+
return False
|
|
430
|
+
return not (isinstance(entity, SoftDeleteTableMixin) and entity.is_soft_deleted)
|
|
423
431
|
|
|
424
432
|
@classmethod
|
|
425
433
|
def get_by_id_for_update(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_pagination.py
RENAMED
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/base/dal/_repository.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/integrations/flask/ext.py
RENAMED
|
File without changes
|
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/__init__.py
RENAMED
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/sync_manager.py
RENAMED
|
File without changes
|
{lush_sqlalchemyx-0.3.2 → lush_sqlalchemyx-0.4.1}/src/lush_sqlalchemyx/mgrs/mysql/sync_mapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|