fastapi-sqlalchemy-toolkit 0.8.2.2__tar.gz → 0.8.2.3__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.
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/PKG-INFO +1 -1
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/filtering.md +21 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/filtering.md +4 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/fastapi_sqlalchemy_toolkit/model_manager.py +22 -9
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/pyproject.toml +1 -1
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/test_public_methods.py +116 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/.flake8 +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/.github/workflows/docker-test.yml +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/.github/workflows/python-publish.yml +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/.gitignore +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/.pylintrc +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/AUTHORS +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/LICENSE +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/Makefile +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/README.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/benefits.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/db_validation.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/extension.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/index.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/benefits.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/db_validation.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/extension.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/index.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/sorting.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/transactions.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/usage.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/utils.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/sorting.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/transactions.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/usage.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/utils.md +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/.env +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/__init__.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/__init__.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/api.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/deps.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/endpoints/__init__.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/endpoints/child.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/config.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/db.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/main.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/managers.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/models.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/schemas.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/fastapi_sqlalchemy_toolkit/__init__.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/fastapi_sqlalchemy_toolkit/filters.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/fastapi_sqlalchemy_toolkit/ordering.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/fastapi_sqlalchemy_toolkit/utils.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/mkdocs.yml +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/poetry.lock +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/base.txt +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/docs.txt +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/lint.txt +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/test.txt +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/Dockerfile +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/__init__.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/conftest.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/db.py +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/docker-compose.yml +0 -0
- {fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/models.py +0 -0
|
@@ -278,6 +278,27 @@ async def get_parents(
|
|
|
278
278
|
|
|
279
279
|
`GET /parents?title=foo&slug=bar` — both filters are applied with `AND`.
|
|
280
280
|
|
|
281
|
+
**Case 4: Expression with a falsy value** (`MyModel.column.in_(value)`, `MyModel.column.endswith(value)`, `MyModel.column.startswith(value)`)
|
|
282
|
+
|
|
283
|
+
If `value` is an empty list (`[]`) or an empty string (`""`), the filter is skipped.
|
|
284
|
+
This covers `in_([])`, `endswith("")`, `startswith("")` and similar operators.
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
@router.get("/parents")
|
|
288
|
+
async def get_parents(
|
|
289
|
+
session: Session,
|
|
290
|
+
slugs: list[str] = Query(default=[]),
|
|
291
|
+
) -> list[ParentListSchema]:
|
|
292
|
+
return await parent_manager.list(
|
|
293
|
+
session,
|
|
294
|
+
optional_where=Parent.slug.in_(slugs),
|
|
295
|
+
)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
`GET /parents` — no filter applied, all `Parent` objects are returned.
|
|
299
|
+
|
|
300
|
+
`GET /parents?slugs=foo&slugs=bar` — only `Parent` objects whose `slug` is in `['foo', 'bar']` are returned.
|
|
301
|
+
|
|
281
302
|
> **Note**: nesting of compound expressions (e.g. `(a & b) | c`) is not supported.
|
|
282
303
|
|
|
283
304
|
**Multiple expressions as separate arguments**
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/filtering.md
RENAMED
|
@@ -218,6 +218,10 @@ async def get_parents(
|
|
|
218
218
|
|
|
219
219
|
Аналогично кейсу 1 — если `value` равно `None`, фильтр пропускается.
|
|
220
220
|
|
|
221
|
+
Также если `value` является пустым списком (`[]`) или пустой строкой (`""`), фильтр пропускается.
|
|
222
|
+
Это распространяется на `in_([])`, `endswith("")`, `startswith("")` и аналогичные операторы, которые
|
|
223
|
+
не допускают передачи `None`.
|
|
224
|
+
|
|
221
225
|
```python
|
|
222
226
|
@router.get("/parents")
|
|
223
227
|
async def get_parents(
|
|
@@ -26,7 +26,7 @@ from sqlalchemy.orm import DeclarativeBase, contains_eager, load_only
|
|
|
26
26
|
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
|
27
27
|
from sqlalchemy.orm.relationships import Relationship
|
|
28
28
|
from sqlalchemy.sql import Select
|
|
29
|
-
from sqlalchemy.sql.elements import Null, UnaryExpression
|
|
29
|
+
from sqlalchemy.sql.elements import BindParameter, Null, UnaryExpression
|
|
30
30
|
from sqlalchemy.sql.expression import BinaryExpression, ColumnElement
|
|
31
31
|
from sqlalchemy.sql.functions import Function
|
|
32
32
|
from sqlalchemy.sql.schema import ScalarElementColumnDefault
|
|
@@ -46,6 +46,15 @@ def sqlalchemy_model_to_dict(model: DeclarativeBase) -> dict:
|
|
|
46
46
|
return db_obj_dict
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
def _is_falsy_bind_param(right: Any) -> bool:
|
|
50
|
+
"""Return True if *right* is a BindParameter with a falsy str or list value."""
|
|
51
|
+
return (
|
|
52
|
+
isinstance(right, BindParameter)
|
|
53
|
+
and isinstance(right.value, str | list)
|
|
54
|
+
and not right.value
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
49
58
|
def _get_model_pk(model: type[DeclarativeBase]) -> InstrumentedAttribute:
|
|
50
59
|
"""Получить атрибут первичного ключа для произвольной модели."""
|
|
51
60
|
pk_columns = list(model.__table__.primary_key.columns)
|
|
@@ -1236,16 +1245,20 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
|
|
|
1236
1245
|
@classmethod
|
|
1237
1246
|
def handle_optional_where_expression(cls, optional_where: Any) -> Any:
|
|
1238
1247
|
"""
|
|
1239
|
-
Обрабатывает одно выражение optional_where, пропуская фильтр,
|
|
1248
|
+
Обрабатывает одно выражение optional_where, пропуская фильтр,
|
|
1249
|
+
если его значение None.
|
|
1240
1250
|
|
|
1241
1251
|
Поддерживает:
|
|
1242
1252
|
1. Простые выражения вида MyModel.field == value
|
|
1243
1253
|
2. Выражения с функциями/операторами вида func.date(MyModel.field) == value
|
|
1244
1254
|
3. Составные выражения вида (expr1) & (expr2) или (expr1) | (expr2)
|
|
1245
1255
|
(без вложенности)
|
|
1256
|
+
4. Выражения с "пустым" значением вида MyModel.column.in_([]),
|
|
1257
|
+
MyModel.column.endswith(""), MyModel.column.startswith("")
|
|
1246
1258
|
|
|
1247
|
-
Если value равно None
|
|
1248
|
-
|
|
1259
|
+
Если value равно None или является пустой строкой/списком,
|
|
1260
|
+
фильтр не применяется.
|
|
1261
|
+
В составных выражениях исключаются части с такими значениями,
|
|
1249
1262
|
при этом оператор & или | сохраняется.
|
|
1250
1263
|
"""
|
|
1251
1264
|
if optional_where is None:
|
|
@@ -1257,17 +1270,17 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
|
|
|
1257
1270
|
clause
|
|
1258
1271
|
for clause in optional_where.clauses
|
|
1259
1272
|
if not isinstance(clause.right, Null)
|
|
1273
|
+
and not _is_falsy_bind_param(getattr(clause, "right", None))
|
|
1260
1274
|
]
|
|
1261
1275
|
if not remaining:
|
|
1262
1276
|
return None
|
|
1263
1277
|
if len(remaining) == 1:
|
|
1264
1278
|
return remaining[0]
|
|
1265
|
-
if optional_where.operator.__name__ == "and_"
|
|
1266
|
-
|
|
1267
|
-
return or_(*remaining)
|
|
1279
|
+
combiner = and_ if optional_where.operator.__name__ == "and_" else or_
|
|
1280
|
+
return combiner(*remaining)
|
|
1268
1281
|
|
|
1269
|
-
|
|
1270
|
-
if isinstance(
|
|
1282
|
+
right = getattr(optional_where, "right", None)
|
|
1283
|
+
if isinstance(right, Null) or _is_falsy_bind_param(right):
|
|
1271
1284
|
return None
|
|
1272
1285
|
return optional_where
|
|
1273
1286
|
|
|
@@ -1079,6 +1079,122 @@ async def test_list_with_optional_where_multi_all_none(session: AsyncSession):
|
|
|
1079
1079
|
assert len(parents) == 2
|
|
1080
1080
|
|
|
1081
1081
|
|
|
1082
|
+
async def test_list_with_optional_where_in_applied(session: AsyncSession):
|
|
1083
|
+
"""Case 4: in_ expression, non-empty list — filter is applied."""
|
|
1084
|
+
target_slug = "optional-where-in-slug1"
|
|
1085
|
+
await session.execute(
|
|
1086
|
+
insert(Parent),
|
|
1087
|
+
[
|
|
1088
|
+
{"title": "optional-where-in-title-1", "slug": target_slug},
|
|
1089
|
+
{"title": "optional-where-in-title-2", "slug": "optional-where-in-slug2"},
|
|
1090
|
+
],
|
|
1091
|
+
)
|
|
1092
|
+
await session.commit()
|
|
1093
|
+
|
|
1094
|
+
parents = await parent_manager.list(
|
|
1095
|
+
session=session,
|
|
1096
|
+
optional_where=Parent.slug.in_([target_slug]),
|
|
1097
|
+
)
|
|
1098
|
+
assert len(parents) == 1
|
|
1099
|
+
assert parents[0].slug == target_slug
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
async def test_list_with_optional_where_in_skipped(session: AsyncSession):
|
|
1103
|
+
"""Case 4: in_ expression, empty list — filter is skipped (all returned)."""
|
|
1104
|
+
await session.execute(
|
|
1105
|
+
insert(Parent),
|
|
1106
|
+
[
|
|
1107
|
+
{
|
|
1108
|
+
"title": "optional-where-in-skip-title-1",
|
|
1109
|
+
"slug": "optional-where-in-skip-slug1",
|
|
1110
|
+
},
|
|
1111
|
+
{
|
|
1112
|
+
"title": "optional-where-in-skip-title-2",
|
|
1113
|
+
"slug": "optional-where-in-skip-slug2",
|
|
1114
|
+
},
|
|
1115
|
+
],
|
|
1116
|
+
)
|
|
1117
|
+
await session.commit()
|
|
1118
|
+
|
|
1119
|
+
parents = await parent_manager.list(
|
|
1120
|
+
session=session,
|
|
1121
|
+
optional_where=Parent.slug.in_([]),
|
|
1122
|
+
)
|
|
1123
|
+
assert len(parents) == 2
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
async def test_list_with_optional_where_endswith_applied(session: AsyncSession):
|
|
1127
|
+
"""Case 4: endswith expression, non-empty string — filter is applied."""
|
|
1128
|
+
target_slug = "optional-where-ends-slug-xyz"
|
|
1129
|
+
await session.execute(
|
|
1130
|
+
insert(Parent),
|
|
1131
|
+
[
|
|
1132
|
+
{"title": "optional-where-ends-title-1", "slug": target_slug},
|
|
1133
|
+
{
|
|
1134
|
+
"title": "optional-where-ends-title-2",
|
|
1135
|
+
"slug": "optional-where-ends-slug-abc",
|
|
1136
|
+
},
|
|
1137
|
+
],
|
|
1138
|
+
)
|
|
1139
|
+
await session.commit()
|
|
1140
|
+
|
|
1141
|
+
parents = await parent_manager.list(
|
|
1142
|
+
session=session,
|
|
1143
|
+
optional_where=Parent.slug.endswith("xyz"),
|
|
1144
|
+
)
|
|
1145
|
+
assert len(parents) == 1
|
|
1146
|
+
assert parents[0].slug == target_slug
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
async def test_list_with_optional_where_endswith_skipped(session: AsyncSession):
|
|
1150
|
+
"""Case 4: endswith expression, empty string — filter is skipped (all returned)."""
|
|
1151
|
+
await session.execute(
|
|
1152
|
+
insert(Parent),
|
|
1153
|
+
[
|
|
1154
|
+
{
|
|
1155
|
+
"title": "optional-where-ends-skip-title-1",
|
|
1156
|
+
"slug": "optional-where-ends-skip-slug1",
|
|
1157
|
+
},
|
|
1158
|
+
{
|
|
1159
|
+
"title": "optional-where-ends-skip-title-2",
|
|
1160
|
+
"slug": "optional-where-ends-skip-slug2",
|
|
1161
|
+
},
|
|
1162
|
+
],
|
|
1163
|
+
)
|
|
1164
|
+
await session.commit()
|
|
1165
|
+
|
|
1166
|
+
parents = await parent_manager.list(
|
|
1167
|
+
session=session,
|
|
1168
|
+
optional_where=Parent.slug.endswith(""),
|
|
1169
|
+
)
|
|
1170
|
+
assert len(parents) == 2
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
async def test_list_with_optional_where_in_compound_one_empty(session: AsyncSession):
|
|
1174
|
+
"""Case 4 in compound: in_([]) in & expression — only non-empty filter applied."""
|
|
1175
|
+
target_title = "optional-where-compound-in-title"
|
|
1176
|
+
await session.execute(
|
|
1177
|
+
insert(Parent),
|
|
1178
|
+
[
|
|
1179
|
+
{"title": target_title, "slug": "optional-where-compound-in-slug1"},
|
|
1180
|
+
{"title": target_title, "slug": "optional-where-compound-in-slug2"},
|
|
1181
|
+
{
|
|
1182
|
+
"title": "optional-where-compound-in-other",
|
|
1183
|
+
"slug": "optional-where-compound-in-slug3",
|
|
1184
|
+
},
|
|
1185
|
+
],
|
|
1186
|
+
)
|
|
1187
|
+
await session.commit()
|
|
1188
|
+
|
|
1189
|
+
parents = await parent_manager.list(
|
|
1190
|
+
session=session,
|
|
1191
|
+
optional_where=(Parent.title == target_title) & Parent.slug.in_([]),
|
|
1192
|
+
)
|
|
1193
|
+
assert len(parents) == 2
|
|
1194
|
+
for parent in parents:
|
|
1195
|
+
assert parent.title == target_title
|
|
1196
|
+
|
|
1197
|
+
|
|
1082
1198
|
async def test_create_unique_constraint_validation(session: AsyncSession):
|
|
1083
1199
|
await parent_manager.create(
|
|
1084
1200
|
session=session,
|
|
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
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/db_validation.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/benefits.md
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/db_validation.md
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/extension.md
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/sorting.md
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/ru/transactions.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/docs/transactions.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/api.py
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/api/deps.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/config.py
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/db.py
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/main.py
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/managers.py
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/models.py
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/examples/app/schemas.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/base.txt
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/docs.txt
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/lint.txt
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/requirements/test.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_sqlalchemy_toolkit-0.8.2.2 → fastapi_sqlalchemy_toolkit-0.8.2.3}/tests/docker-compose.yml
RENAMED
|
File without changes
|
|
File without changes
|