lush-sqlalchemyx 0.4.2__tar.gz → 0.6.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.
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/PKG-INFO +1 -1
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/pyproject.toml +7 -1
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/__init__.py +14 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/dal/__init__.py +24 -12
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/dal/_async.py +2 -106
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/dal/_common.py +5 -46
- lush_sqlalchemyx-0.6.0/src/lush_sqlalchemyx/base/dal/_dynamic.py +857 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/dal/_sync.py +1 -106
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/mgrs/mysql/__init__.py +4 -0
- lush_sqlalchemyx-0.6.0/src/lush_sqlalchemyx/mgrs/mysql/_pool_config.py +49 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/mgrs/mysql/manager.py +14 -14
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/mgrs/mysql/sync_manager.py +13 -12
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/shortcuts/meta.py +7 -27
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/README.md +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/_compat.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/__init__.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/dal/_pagination.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/base/dal/_repository.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/integrations/__init__.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/integrations/fastapi/__init__.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/integrations/fastapi/depends/__init__.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/integrations/flask/__init__.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/integrations/flask/ext.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/mgrs/__init__.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/mgrs/mysql/mapper.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/mgrs/mysql/sync_mapper.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/py.typed +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/same_impl_just_warn_wrapper.py +0 -0
- {lush_sqlalchemyx-0.4.2 → lush_sqlalchemyx-0.6.0}/src/lush_sqlalchemyx/shortcuts/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lush-sqlalchemyx"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
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"
|
|
@@ -40,6 +40,7 @@ dev = [
|
|
|
40
40
|
"jinja2sql>=0.8.0",
|
|
41
41
|
"pytest>=8.4.1",
|
|
42
42
|
"pytest-asyncio>=1.1.0",
|
|
43
|
+
"pytest-bdd>=8.1.0",
|
|
43
44
|
"pytest-cov>=6.2.1",
|
|
44
45
|
"aiosqlite>=0.20.0",
|
|
45
46
|
"aiomysql>=0.2.0",
|
|
@@ -57,11 +58,15 @@ testpaths = ["tests"]
|
|
|
57
58
|
asyncio_mode = "auto"
|
|
58
59
|
asyncio_default_fixture_loop_scope = "function"
|
|
59
60
|
asyncio_default_test_loop_scope = "function"
|
|
61
|
+
bdd_features_base_dir = "tests/features"
|
|
60
62
|
|
|
61
63
|
[tool.coverage.run]
|
|
62
64
|
branch = true
|
|
63
65
|
|
|
64
66
|
[tool.coverage.report]
|
|
67
|
+
precision = 2
|
|
68
|
+
show_missing = true
|
|
69
|
+
skip_covered = true
|
|
65
70
|
exclude_also = [
|
|
66
71
|
"if TYPE_CHECKING:",
|
|
67
72
|
"if __name__ == .__main__.:",
|
|
@@ -169,6 +174,7 @@ ignore = [
|
|
|
169
174
|
"S101", # assert语句(测试中使用)
|
|
170
175
|
"S105", # 硬编码密码字符串
|
|
171
176
|
"S201", # Flask debug=True
|
|
177
|
+
"S608", # SQL注入(测试辅助函数的硬编码表名)
|
|
172
178
|
"S301", # 可疑的pickle使用
|
|
173
179
|
"S311", # 非加密安全的随机数
|
|
174
180
|
|
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from lush_sqlalchemyx.base.dal import (
|
|
13
|
+
DynamicAsyncDAL,
|
|
14
|
+
DynamicSyncDAL,
|
|
15
|
+
DynamicTableConfig,
|
|
16
|
+
PrimaryKeyT,
|
|
17
|
+
TableRef,
|
|
18
|
+
derive_columns_from_dto,
|
|
19
|
+
derive_pk_from_dto,
|
|
13
20
|
is_soft_delete_hooks_registered,
|
|
14
21
|
register_soft_delete_hooks,
|
|
15
22
|
setup_dal_hooks,
|
|
@@ -17,6 +24,13 @@ from lush_sqlalchemyx.base.dal import (
|
|
|
17
24
|
)
|
|
18
25
|
|
|
19
26
|
__all__ = (
|
|
27
|
+
"DynamicAsyncDAL",
|
|
28
|
+
"DynamicSyncDAL",
|
|
29
|
+
"DynamicTableConfig",
|
|
30
|
+
"PrimaryKeyT",
|
|
31
|
+
"TableRef",
|
|
32
|
+
"derive_columns_from_dto",
|
|
33
|
+
"derive_pk_from_dto",
|
|
20
34
|
"is_soft_delete_hooks_registered",
|
|
21
35
|
"register_soft_delete_hooks",
|
|
22
36
|
"setup_dal_hooks",
|
|
@@ -28,8 +28,7 @@ from ._async import (
|
|
|
28
28
|
BasicAsyncBaseTable,
|
|
29
29
|
ReadOnlyAsyncBaseDAL,
|
|
30
30
|
ReadOnlyBasicAsyncBaseTable,
|
|
31
|
-
|
|
32
|
-
StdReadOnlyBasicAsyncBaseTable,
|
|
31
|
+
|
|
33
32
|
async_temp_set_lock_wait_timeout,
|
|
34
33
|
async_with_retry,
|
|
35
34
|
)
|
|
@@ -49,8 +48,7 @@ from ._common import (
|
|
|
49
48
|
RetryConfig,
|
|
50
49
|
SoftDeleteTableMixin,
|
|
51
50
|
SQLATableT,
|
|
52
|
-
|
|
53
|
-
StdBaseDTO,
|
|
51
|
+
|
|
54
52
|
escape_like,
|
|
55
53
|
filtered_in_sql_values,
|
|
56
54
|
is_soft_delete_hooks_registered,
|
|
@@ -62,6 +60,17 @@ from ._common import (
|
|
|
62
60
|
# Event listener references — accessed by tests via getattr(module, name).
|
|
63
61
|
from ._common import __prevent_readonly_write as __prevent_readonly_write # pyright: ignore[reportPrivateUsage]
|
|
64
62
|
from ._common import __receive_before_flush as __receive_before_flush # pyright: ignore[reportPrivateUsage]
|
|
63
|
+
|
|
64
|
+
# --- dynamic (no ORM table class) ---
|
|
65
|
+
from ._dynamic import (
|
|
66
|
+
DynamicAsyncDAL,
|
|
67
|
+
DynamicSyncDAL,
|
|
68
|
+
DynamicTableConfig,
|
|
69
|
+
PrimaryKeyT,
|
|
70
|
+
TableRef,
|
|
71
|
+
derive_columns_from_dto,
|
|
72
|
+
derive_pk_from_dto,
|
|
73
|
+
)
|
|
65
74
|
from ._pagination import (
|
|
66
75
|
build_cursor_stmt,
|
|
67
76
|
build_offset_stmt,
|
|
@@ -77,8 +86,7 @@ from ._sync import (
|
|
|
77
86
|
BasicSyncBaseTable,
|
|
78
87
|
ReadOnlySyncBaseDAL,
|
|
79
88
|
ReadOnlySyncBaseTable,
|
|
80
|
-
|
|
81
|
-
StdSyncBaseTable,
|
|
89
|
+
|
|
82
90
|
SyncBaseDAL,
|
|
83
91
|
SyncRawDAL,
|
|
84
92
|
SyncRawReadDAL,
|
|
@@ -108,14 +116,20 @@ __all__ = (
|
|
|
108
116
|
"SQLATableT",
|
|
109
117
|
"SoftDeleteTableMixin",
|
|
110
118
|
"FieldIsDeleteSoftDeleteTableMixin",
|
|
111
|
-
"StdBaseCU",
|
|
112
|
-
"StdBaseDTO",
|
|
113
119
|
"escape_like",
|
|
114
120
|
"filtered_in_sql_values",
|
|
115
121
|
"is_soft_delete_hooks_registered",
|
|
116
122
|
"register_soft_delete_hooks",
|
|
117
123
|
"setup_dal_hooks",
|
|
118
124
|
"unregister_soft_delete_hooks",
|
|
125
|
+
# dynamic
|
|
126
|
+
"DynamicAsyncDAL",
|
|
127
|
+
"DynamicSyncDAL",
|
|
128
|
+
"DynamicTableConfig",
|
|
129
|
+
"PrimaryKeyT",
|
|
130
|
+
"TableRef",
|
|
131
|
+
"derive_columns_from_dto",
|
|
132
|
+
"derive_pk_from_dto",
|
|
119
133
|
# async
|
|
120
134
|
"AsyncBaseDAL",
|
|
121
135
|
"AsyncRawDAL",
|
|
@@ -128,16 +142,14 @@ __all__ = (
|
|
|
128
142
|
"BasicAsyncBaseTable",
|
|
129
143
|
"ReadOnlyAsyncBaseDAL",
|
|
130
144
|
"ReadOnlyBasicAsyncBaseTable",
|
|
131
|
-
|
|
132
|
-
"StdReadOnlyBasicAsyncBaseTable",
|
|
145
|
+
|
|
133
146
|
"async_temp_set_lock_wait_timeout",
|
|
134
147
|
"async_with_retry",
|
|
135
148
|
# sync
|
|
136
149
|
"BasicSyncBaseTable",
|
|
137
150
|
"ReadOnlySyncBaseDAL",
|
|
138
151
|
"ReadOnlySyncBaseTable",
|
|
139
|
-
|
|
140
|
-
"StdSyncBaseTable",
|
|
152
|
+
|
|
141
153
|
"SyncBaseDAL",
|
|
142
154
|
"SyncRawDAL",
|
|
143
155
|
"SyncRawReadDAL",
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
import asyncio
|
|
10
|
-
import datetime
|
|
11
10
|
import logging
|
|
12
|
-
import warnings
|
|
13
11
|
from collections.abc import AsyncGenerator, Awaitable, Callable, Iterable
|
|
14
12
|
from contextlib import asynccontextmanager, suppress
|
|
15
13
|
from typing import TYPE_CHECKING, Any, ClassVar, Generic, Literal, ParamSpec, TypeVar, cast
|
|
@@ -19,7 +17,7 @@ from lush_dal_protocol.abc import AbstractAsyncReadDAL, AbstractAsyncWriteDAL
|
|
|
19
17
|
from pydantic import BaseModel
|
|
20
18
|
from sqlalchemy import ColumnExpressionArgument
|
|
21
19
|
from sqlalchemy.ext.asyncio import AsyncAttrs, AsyncSession
|
|
22
|
-
from sqlalchemy.orm import DeclarativeBase, InstrumentedAttribute
|
|
20
|
+
from sqlalchemy.orm import DeclarativeBase, InstrumentedAttribute
|
|
23
21
|
|
|
24
22
|
from lush_sqlalchemyx._compat import require_async
|
|
25
23
|
|
|
@@ -31,7 +29,6 @@ from ._common import (
|
|
|
31
29
|
CUModelT,
|
|
32
30
|
DBRetryableError,
|
|
33
31
|
DTOModelT,
|
|
34
|
-
FieldIsDeleteSoftDeleteTableMixin,
|
|
35
32
|
ReadOnlyMixin,
|
|
36
33
|
RetryConfig,
|
|
37
34
|
SoftDeleteTableMixin,
|
|
@@ -143,106 +140,6 @@ class ReadOnlyBasicAsyncBaseTable(AsyncSqlATableBase, ReadOnlyMixin):
|
|
|
143
140
|
__abstract__ = True
|
|
144
141
|
|
|
145
142
|
|
|
146
|
-
class StdAsyncBaseTable(BasicAsyncBaseTable, FieldIsDeleteSoftDeleteTableMixin):
|
|
147
|
-
"""标准异步表类: 包含 id/时间戳/操作人/软删除等标准字段.
|
|
148
|
-
|
|
149
|
-
.. deprecated::
|
|
150
|
-
此类预设了特定业务字段, 下游应自行继承 ``BasicAsyncBaseTable`` 定义所需字段.
|
|
151
|
-
"""
|
|
152
|
-
|
|
153
|
-
__abstract__ = True
|
|
154
|
-
|
|
155
|
-
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
156
|
-
super().__init_subclass__(**kwargs)
|
|
157
|
-
if not cls.__dict__.get("__abstract__", False):
|
|
158
|
-
warnings.warn(
|
|
159
|
-
f"{cls.__name__} 继承了已废弃的 StdAsyncBaseTable, 请改为直接继承 BasicAsyncBaseTable 并自行定义所需字段",
|
|
160
|
-
DeprecationWarning,
|
|
161
|
-
stacklevel=2,
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
id: Mapped[int] = mapped_column(sa.Integer, primary_key=True, autoincrement=True)
|
|
165
|
-
|
|
166
|
-
create_datetime: Mapped[datetime.datetime] = mapped_column(
|
|
167
|
-
sa.DateTime,
|
|
168
|
-
nullable=False,
|
|
169
|
-
comment="创建时间",
|
|
170
|
-
server_default=sa.sql.func.now(),
|
|
171
|
-
server_onupdate=sa.FetchedValue(),
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
create_operator_id: Mapped[int] = mapped_column(
|
|
175
|
-
sa.Integer,
|
|
176
|
-
nullable=False,
|
|
177
|
-
comment="创建人",
|
|
178
|
-
default=0,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
update_datetime: Mapped[datetime.datetime] = mapped_column(
|
|
182
|
-
sa.DateTime,
|
|
183
|
-
nullable=True,
|
|
184
|
-
comment="修改时间",
|
|
185
|
-
server_default=sa.sql.func.now(),
|
|
186
|
-
onupdate=sa.sql.func.now(),
|
|
187
|
-
server_onupdate=sa.FetchedValue(),
|
|
188
|
-
)
|
|
189
|
-
update_operator_id: Mapped[int | None] = mapped_column(
|
|
190
|
-
sa.Integer,
|
|
191
|
-
nullable=True,
|
|
192
|
-
comment="修改人",
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
class StdReadOnlyBasicAsyncBaseTable(ReadOnlyBasicAsyncBaseTable):
|
|
197
|
-
"""标准只读异步表基类: 包含 id/时间戳/操作人等标准字段.
|
|
198
|
-
|
|
199
|
-
.. deprecated::
|
|
200
|
-
此类预设了特定业务字段, 下游应自行继承 ``ReadOnlyBasicAsyncBaseTable`` 定义所需字段.
|
|
201
|
-
"""
|
|
202
|
-
|
|
203
|
-
__abstract__ = True
|
|
204
|
-
|
|
205
|
-
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
206
|
-
super().__init_subclass__(**kwargs)
|
|
207
|
-
if not cls.__dict__.get("__abstract__", False):
|
|
208
|
-
warnings.warn(
|
|
209
|
-
f"{cls.__name__} 继承了已废弃的 StdReadOnlyBasicAsyncBaseTable, 请改为直接继承 ReadOnlyBasicAsyncBaseTable 并自行定义所需字段",
|
|
210
|
-
DeprecationWarning,
|
|
211
|
-
stacklevel=2,
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
id: Mapped[int] = mapped_column(sa.Integer, primary_key=True, autoincrement=True)
|
|
215
|
-
|
|
216
|
-
create_datetime: Mapped[datetime.datetime] = mapped_column(
|
|
217
|
-
sa.DateTime,
|
|
218
|
-
nullable=False,
|
|
219
|
-
comment="创建时间",
|
|
220
|
-
server_default=sa.sql.func.now(),
|
|
221
|
-
server_onupdate=sa.FetchedValue(),
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
create_operator_id: Mapped[int] = mapped_column(
|
|
225
|
-
sa.Integer,
|
|
226
|
-
nullable=False,
|
|
227
|
-
comment="创建人",
|
|
228
|
-
default=0,
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
update_datetime: Mapped[datetime.datetime] = mapped_column(
|
|
232
|
-
sa.DateTime,
|
|
233
|
-
nullable=True,
|
|
234
|
-
comment="修改时间",
|
|
235
|
-
server_default=sa.sql.func.now(),
|
|
236
|
-
onupdate=sa.sql.func.now(),
|
|
237
|
-
server_onupdate=sa.FetchedValue(),
|
|
238
|
-
)
|
|
239
|
-
update_operator_id: Mapped[int | None] = mapped_column(
|
|
240
|
-
sa.Integer,
|
|
241
|
-
nullable=True,
|
|
242
|
-
comment="修改人",
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
|
|
246
143
|
# ---------------------------------------------------------------------------
|
|
247
144
|
# Async DAL hierarchy
|
|
248
145
|
# ---------------------------------------------------------------------------
|
|
@@ -905,8 +802,7 @@ __all__ = (
|
|
|
905
802
|
"BasicAsyncBaseTable",
|
|
906
803
|
"ReadOnlyAsyncBaseDAL",
|
|
907
804
|
"ReadOnlyBasicAsyncBaseTable",
|
|
908
|
-
|
|
909
|
-
"StdReadOnlyBasicAsyncBaseTable",
|
|
805
|
+
|
|
910
806
|
"async_temp_set_lock_wait_timeout",
|
|
911
807
|
"async_with_retry",
|
|
912
808
|
)
|
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
import datetime
|
|
9
8
|
import logging
|
|
10
9
|
import random
|
|
11
|
-
import warnings
|
|
12
10
|
from collections.abc import Callable, Iterable
|
|
13
11
|
from dataclasses import dataclass
|
|
14
12
|
from typing import Any, ClassVar, Final, Generic, TypeVar, cast
|
|
@@ -18,7 +16,7 @@ from lush_dal_protocol.dto import BaseCU as _ProtocolBaseCU
|
|
|
18
16
|
from lush_dal_protocol.dto import BaseDTO as _ProtocolBaseDTO
|
|
19
17
|
from lush_dal_protocol.dto import CUModelT as CUModelT # noqa: PLC0414
|
|
20
18
|
from lush_dal_protocol.dto import DTOModelT as DTOModelT # noqa: PLC0414
|
|
21
|
-
from pydantic import BaseModel, ConfigDict
|
|
19
|
+
from pydantic import BaseModel, ConfigDict
|
|
22
20
|
from sqlalchemy import event as sa_event
|
|
23
21
|
from sqlalchemy.exc import OperationalError as SQLAlchemyOperationalError
|
|
24
22
|
from sqlalchemy.orm import Mapped, ORMExecuteState, mapped_column, with_loader_criteria
|
|
@@ -163,47 +161,7 @@ class BaseDTO(_ProtocolBaseDTO[CUModelT]):
|
|
|
163
161
|
model_config = ConfigDict(from_attributes=True)
|
|
164
162
|
|
|
165
163
|
|
|
166
|
-
class StdBaseCU(BaseCU[SQLATableT]):
|
|
167
|
-
"""标准 CU 基类: 包含创建人/修改人等标准字段.
|
|
168
164
|
|
|
169
|
-
.. deprecated::
|
|
170
|
-
此类预设了特定业务字段, 下游应自行继承 ``BaseCU`` 定义所需字段.
|
|
171
|
-
"""
|
|
172
|
-
|
|
173
|
-
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
174
|
-
super().__init_subclass__(**kwargs)
|
|
175
|
-
warnings.warn(
|
|
176
|
-
f"{cls.__name__} 继承了已废弃的 StdBaseCU, 请改为直接继承 BaseCU 并自行定义所需字段",
|
|
177
|
-
DeprecationWarning,
|
|
178
|
-
stacklevel=2,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
create_operator_id: int = 0
|
|
182
|
-
update_operator_id: int | None = None
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
class StdBaseDTO(BaseDTO[CUModelT]):
|
|
186
|
-
"""标准 DTO 基类: 包含 id/时间戳/操作人等标准字段.
|
|
187
|
-
|
|
188
|
-
.. deprecated::
|
|
189
|
-
此类预设了特定业务字段, 下游应自行继承 ``BaseDTO`` 定义所需字段.
|
|
190
|
-
"""
|
|
191
|
-
|
|
192
|
-
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
193
|
-
super().__init_subclass__(**kwargs)
|
|
194
|
-
warnings.warn(
|
|
195
|
-
f"{cls.__name__} 继承了已废弃的 StdBaseDTO, 请改为直接继承 BaseDTO 并自行定义所需字段",
|
|
196
|
-
DeprecationWarning,
|
|
197
|
-
stacklevel=2,
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
id: int = Field(..., description="ID")
|
|
201
|
-
create_datetime: datetime.datetime = Field(..., description="创建时间")
|
|
202
|
-
create_operator_id: int = Field(..., description="创建人")
|
|
203
|
-
update_datetime: datetime.datetime | None = Field(None, description="修改时间")
|
|
204
|
-
update_operator_id: int | None = Field(None, description="修改人")
|
|
205
|
-
|
|
206
|
-
model_config = ConfigDict(from_attributes=True)
|
|
207
165
|
|
|
208
166
|
|
|
209
167
|
# ---------------------------------------------------------------------------
|
|
@@ -256,7 +214,9 @@ class FieldIsDeleteSoftDeleteTableMixin(SoftDeleteTableMixin):
|
|
|
256
214
|
等价旧版 ``SoftDeleteTableMixin``,仅需 rename.
|
|
257
215
|
"""
|
|
258
216
|
|
|
259
|
-
is_delete: Mapped[int] = mapped_column(
|
|
217
|
+
is_delete: Mapped[int] = mapped_column(
|
|
218
|
+
sa.SmallInteger, default=0, comment="逻辑删除"
|
|
219
|
+
) # NOTE(@l8ng): 可以优化, 比如给个配置配置mysql可以用tinyint, 现在用 smallint 是因为基本主流数据库都支持
|
|
260
220
|
|
|
261
221
|
|
|
262
222
|
class ReadOnlyMixin:
|
|
@@ -452,8 +412,7 @@ __all__ = (
|
|
|
452
412
|
"SQLATableT",
|
|
453
413
|
"SQLAlchemyOperationalError",
|
|
454
414
|
"SoftDeleteTableMixin",
|
|
455
|
-
|
|
456
|
-
"StdBaseDTO",
|
|
415
|
+
|
|
457
416
|
"T",
|
|
458
417
|
"V",
|
|
459
418
|
"_ensure_strict_fields",
|