sqlmodel-object-helpers 0.0.7__tar.gz → 0.0.9__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.
- sqlmodel_object_helpers-0.0.9/.git-blame-ignore-revs +5 -0
- sqlmodel_object_helpers-0.0.9/.gitattributes +16 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/.gitignore +11 -1
- sqlmodel_object_helpers-0.0.9/.vscode/settings.json +81 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/PKG-INFO +36 -13
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/README.md +32 -3
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/pyproject.toml +12 -22
- sqlmodel_object_helpers-0.0.9/pyrightconfig.json +38 -0
- sqlmodel_object_helpers-0.0.9/ruff.toml +129 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/__init__.py +29 -28
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/constants.py +42 -42
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/dynamic_meta.py +18 -28
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/filters.py +57 -29
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/loaders.py +3 -1
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/mutations.py +508 -498
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/operators.py +7 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/query.py +287 -138
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/session.py +162 -153
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/standalone.py +193 -19
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/types/datetime.py +3 -6
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/types/filters.py +5 -10
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/conftest.py +810 -750
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_bulk_mutations.py +49 -14
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_column_meta.py +27 -24
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_computed_columns.py +14 -11
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_count_exists.py +45 -18
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_data_error_handling.py +6 -7
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_datetime_range.py +15 -24
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_dynamic_meta.py +113 -65
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_exceptions.py +195 -196
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_filters.py +339 -364
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_for_update.py +5 -3
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_generated_columns_pg.py +15 -9
- sqlmodel_object_helpers-0.0.9/tests/test_implicit_datetime.py +182 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_loaders.py +209 -204
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_mutations.py +418 -386
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_operators.py +191 -192
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_query.py +653 -569
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_settings.py +164 -165
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_standalone.py +195 -86
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_time_filter.py +48 -41
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/tests/test_types.py +859 -857
- sqlmodel_object_helpers-0.0.9/uv.lock +354 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/.github/workflows/publish.yml +0 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/LICENSE +0 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/exceptions.py +0 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/types/__init__.py +0 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/types/columns.py +0 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/types/pagination.py +0 -0
- {sqlmodel_object_helpers-0.0.7 → sqlmodel_object_helpers-0.0.9}/src/sqlmodel_object_helpers/types/projections.py +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Enforce LF line endings for all text files
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
# Explicitly mark as text
|
|
5
|
+
*.py text eol=lf
|
|
6
|
+
*.toml text eol=lf
|
|
7
|
+
*.md text eol=lf
|
|
8
|
+
*.txt text eol=lf
|
|
9
|
+
*.json text eol=lf
|
|
10
|
+
*.yaml text eol=lf
|
|
11
|
+
*.yml text eol=lf
|
|
12
|
+
|
|
13
|
+
# Binary files (no conversion)
|
|
14
|
+
*.png binary
|
|
15
|
+
*.jpg binary
|
|
16
|
+
*.ico binary
|
|
@@ -21,7 +21,8 @@ htmlcov/
|
|
|
21
21
|
|
|
22
22
|
# IDEs
|
|
23
23
|
.idea/
|
|
24
|
-
.vscode
|
|
24
|
+
.vscode/*
|
|
25
|
+
!.vscode/settings.json
|
|
25
26
|
*.swp
|
|
26
27
|
*.swo
|
|
27
28
|
|
|
@@ -32,3 +33,12 @@ htmlcov/
|
|
|
32
33
|
Thumbs.db
|
|
33
34
|
Desktop.ini
|
|
34
35
|
.DS_Store
|
|
36
|
+
|
|
37
|
+
# --- личное окружение разработчика (общий блок ci-templates) ---
|
|
38
|
+
.claude/
|
|
39
|
+
.cursor/
|
|
40
|
+
.windsurf/
|
|
41
|
+
|
|
42
|
+
# --- кеши инструментов ---
|
|
43
|
+
.uv-cache/
|
|
44
|
+
.ruff_cache/
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Общий стандарт python-парка. Настройки редактора.
|
|
3
|
+
// Источник: devops/ci-templates/standards/vscode-settings.json @ v1.18.0
|
|
4
|
+
// Кладётся в репозиторий как .vscode/settings.json.
|
|
5
|
+
//
|
|
6
|
+
// ЛИЧНОЕ СЮДА НЕ ДОПИСЫВАТЬ. Файл общий, его sha256 сверяет блокирующая
|
|
7
|
+
// джоба standards_check. Привычки редактора (autofetch, renderWhitespace,
|
|
8
|
+
// suggest.*, тема) и настройки своих расширений держите в СВОИХ настройках
|
|
9
|
+
// VS Code: Ctrl+Shift+P -> Preferences: Open User Settings (JSON). Оттуда
|
|
10
|
+
// они работают сразу во всех репозиториях парка, а не в одном, и никакой
|
|
11
|
+
// pull их не тронет. Всё прочее в .vscode/ (mcp.json, sftp.json) в git
|
|
12
|
+
// не едет и никогда не ехало.
|
|
13
|
+
|
|
14
|
+
// Главное. Без fromEnvironment расширение берёт СВОЙ встроенный ruff
|
|
15
|
+
// произвольной версии, и результат у разработчика расходится с CI даже при
|
|
16
|
+
// одинаковом конфиге. С этой настройкой берётся ruff из .venv проекта,
|
|
17
|
+
// то есть ровно тот, что запинен в uv.lock и запускается в пайплайне.
|
|
18
|
+
"ruff.importStrategy": "fromEnvironment",
|
|
19
|
+
|
|
20
|
+
// Второе главное. Умолчание расширения — editorFirst: ключи ruff.lint.select,
|
|
21
|
+
// ruff.lint.ignore и ruff.lineLength из настроек редактора ПЕРЕБИВАЮТ
|
|
22
|
+
// ruff.toml. standards_check при этом зелёный — он сверяет сам ruff.toml, —
|
|
23
|
+
// а разработчик локально линтует другим набором правил и форматирует по
|
|
24
|
+
// другой ширине. filesystemFirst возвращает единственный источник правды.
|
|
25
|
+
"ruff.configurationPreference": "filesystemFirst",
|
|
26
|
+
|
|
27
|
+
"python.defaultInterpreterPath": "${workspaceFolder}/.venv",
|
|
28
|
+
|
|
29
|
+
"[python]": {
|
|
30
|
+
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
31
|
+
"editor.formatOnSave": true,
|
|
32
|
+
"editor.codeActionsOnSave": {
|
|
33
|
+
"source.fixAll.ruff": "explicit",
|
|
34
|
+
"source.organizeImports.ruff": "explicit"
|
|
35
|
+
},
|
|
36
|
+
// Линейка совпадает с line-length в ruff.toml.
|
|
37
|
+
"editor.rulers": [120]
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// Проверку типов ведёт pyright по общему pyrightconfig.json,
|
|
41
|
+
// поэтому встроенный анализатор не дублирует его своим режимом.
|
|
42
|
+
"python.analysis.typeCheckingMode": "off",
|
|
43
|
+
"python.analysis.autoImportCompletions": true,
|
|
44
|
+
|
|
45
|
+
// Файлы общего стандарта редактор держит только на чтение. Закрывает частый
|
|
46
|
+
// случай: при "[json]": {"editor.formatOnSave": true} открытие и сохранение
|
|
47
|
+
// pyrightconfig.json переформатирует его и уронит standards_check.
|
|
48
|
+
// Разовая правка — команда «File: Toggle Active Editor Read-only in Session».
|
|
49
|
+
"files.readonlyInclude": {
|
|
50
|
+
"ruff.toml": true,
|
|
51
|
+
"pyrightconfig.json": true,
|
|
52
|
+
".vscode/settings.json": true
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// Команда работает и на Windows, и на Linux, а один случайный CRLF даёт
|
|
56
|
+
// diff на весь файл. Со стороны git то же самое делает .gitattributes.
|
|
57
|
+
"files.eol": "\n",
|
|
58
|
+
"files.trimTrailingWhitespace": true,
|
|
59
|
+
"files.insertFinalNewline": true,
|
|
60
|
+
|
|
61
|
+
// Вотчер .gitignore не читает вообще, исключения ему нужны свои. У
|
|
62
|
+
// sro-agent-core [tool.uv] cache-dir = ".uv-cache" держит кеш пакетов
|
|
63
|
+
// ВНУТРИ репозитория — без этого редактор ходит по распакованным колёсам.
|
|
64
|
+
"files.watcherExclude": {
|
|
65
|
+
"**/__pycache__": true,
|
|
66
|
+
"**/.venv": true,
|
|
67
|
+
"**/.uv-cache": true,
|
|
68
|
+
"**/.ruff_cache": true,
|
|
69
|
+
"**/.pytest_cache": true
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// Поиск по умолчанию уважает .gitignore, но тот дырявый: .uv-cache закрыт
|
|
73
|
+
// в 3 репозиториях из 19, .pytest_cache — в 11.
|
|
74
|
+
"search.exclude": {
|
|
75
|
+
"**/__pycache__": true,
|
|
76
|
+
"**/.venv": true,
|
|
77
|
+
"**/.uv-cache": true,
|
|
78
|
+
"**/.ruff_cache": true,
|
|
79
|
+
"**/.pytest_cache": true
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: sqlmodel-object-helpers
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary: Generic async query helpers for SQLModel: filtering, eager loading, pagination
|
|
5
5
|
Project-URL: Homepage, https://github.com/itstandart/sqlmodel-object-helpers
|
|
6
6
|
Project-URL: Repository, https://github.com/itstandart/sqlmodel-object-helpers
|
|
@@ -22,14 +22,8 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Requires-Python: >=3.14
|
|
24
24
|
Requires-Dist: pydantic>=2.12
|
|
25
|
-
Requires-Dist: sqlalchemy>=2.0.46
|
|
26
|
-
Requires-Dist: sqlmodel>=0.0.
|
|
27
|
-
Provides-Extra: dev
|
|
28
|
-
Requires-Dist: aiosqlite>=0.20; extra == 'dev'
|
|
29
|
-
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
30
|
-
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
31
|
-
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
32
|
-
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.46
|
|
26
|
+
Requires-Dist: sqlmodel>=0.0.27
|
|
33
27
|
Description-Content-Type: text/markdown
|
|
34
28
|
|
|
35
29
|
# sqlmodel-object-helpers
|
|
@@ -295,7 +289,7 @@ result = await soh.get_objects(
|
|
|
295
289
|
users = await soh.get_objects(
|
|
296
290
|
session, User,
|
|
297
291
|
filters={"is_active": {soh.Operator.EQ: True}, "role": {soh.Operator.EQ: "admin"}},
|
|
298
|
-
logical_operator=
|
|
292
|
+
logical_operator=soh.LogicalOperator.OR,
|
|
299
293
|
)
|
|
300
294
|
|
|
301
295
|
# Relationship filters (dot-notation)
|
|
@@ -523,6 +517,8 @@ Used by `get_objects`. Nested dicts are auto-flattened via `flatten_filters`:
|
|
|
523
517
|
|
|
524
518
|
`Operator` is a `StrEnum` — each member equals its string value (`Operator.EQ == "eq"`), so string keys still work but enum members provide type safety and autocompletion.
|
|
525
519
|
|
|
520
|
+
`logical_operator` of `get_objects`, `count_objects`, `update_objects` and `delete_objects` takes `soh.LogicalOperator.AND` (default) or `soh.LogicalOperator.OR`; the strings `"AND"`/`"OR"` in any case still work. Any other value raises `InvalidFilterError`, even with `suspend_error=True`.
|
|
521
|
+
|
|
526
522
|
Multiple operators can be combined on a single field: `{"age": {soh.Operator.GE: 18, soh.Operator.LE: 65}}`.
|
|
527
523
|
|
|
528
524
|
### Typed Filter Models
|
|
@@ -569,6 +565,15 @@ Each date part accepts ISO (`2026-04-01`, `2026-04-01T00:00:00Z`) and display fo
|
|
|
569
565
|
- `FilterDatetimeRange` — produces UTC-aware datetimes
|
|
570
566
|
- `FilterNaiveDatetimeRange` — produces naive (timezone-unaware) datetimes
|
|
571
567
|
|
|
568
|
+
#### Datetime columns and SQLModel ≥0.0.45
|
|
569
|
+
|
|
570
|
+
Since SQLModel 0.0.45 a bare `datetime` field (no `sa_type` / `sa_column`) becomes `UTCDateTime` — `TIMESTAMP WITH TIME ZONE` that rejects naive values and returns UTC-aware ones. soh works on both sides of this change:
|
|
571
|
+
|
|
572
|
+
- Filter such columns with `FilterDatetime`, `FilterDatetimeRange`, `TimeFilter` or aware `datetime` values. A naive value is rejected by SQLModel and surfaces as `soh.DatabaseError`.
|
|
573
|
+
- `FilterNaiveDatetime` / `FilterNaiveDatetimeRange` are for columns declared explicitly as naive: `sa_type=DateTime` or `sa_column=Column(DateTime())`.
|
|
574
|
+
- `build_dynamic_meta` reports `UTCDateTime` columns as `datetime`.
|
|
575
|
+
- SQLModel does not migrate existing database columns. Over an existing `timestamp` column a bare `datetime` field reads values as UTC and, when the PostgreSQL session `TimeZone` is not UTC, writes them shifted by its offset. To keep the current behaviour of a bare `datetime` field, declare its database type explicitly: `sa_column=Column(DateTime())` for `timestamp`, `sa_column=Column(DateTime(timezone=True))` for `timestamptz`.
|
|
576
|
+
|
|
572
577
|
## Eager Loading
|
|
573
578
|
|
|
574
579
|
The library automatically selects the optimal loading strategy:
|
|
@@ -666,8 +671,11 @@ Physical column types are mapped automatically. Unknown types fall back to `stri
|
|
|
666
671
|
| `Integer`, `BigInteger`, `SmallInteger` | `integer` |
|
|
667
672
|
| `Numeric`, `Float` | `float` |
|
|
668
673
|
| `String`, `Text`, `Enum`, `Interval`, `ARRAY`, `Uuid` | `string` |
|
|
674
|
+
| Unmapped `TypeDecorator` (e.g. SQLModel `UTCDateTime`) | type of its `impl` |
|
|
669
675
|
| Any other type | `string` (fallback) |
|
|
670
676
|
|
|
677
|
+
`Interval` is a `TypeDecorator` over `DateTime`, but its own entry wins, so it stays `string`.
|
|
678
|
+
|
|
671
679
|
### Label precedence (per physical column)
|
|
672
680
|
|
|
673
681
|
1. `pg_description` — DBA edit via `COMMENT ON COLUMN` (supports per-role `||` overrides)
|
|
@@ -783,6 +791,7 @@ Endpoints can be migrated one at a time. Three strategies per endpoint:
|
|
|
783
791
|
### Operators
|
|
784
792
|
|
|
785
793
|
- `soh.Operator` -- StrEnum of operator names
|
|
794
|
+
- `soh.LogicalOperator` -- StrEnum `AND`/`OR` for the `logical_operator` argument
|
|
786
795
|
- `soh.SUPPORTED_OPERATORS` -- Dict mapping operator names to SQLAlchemy lambdas
|
|
787
796
|
- `soh.SPECIAL_OPERATORS` -- Frozenset of operators with extended handling (`{"exists"}`)
|
|
788
797
|
|
|
@@ -837,8 +846,8 @@ Endpoints can be migrated one at a time. Three strategies per endpoint:
|
|
|
837
846
|
## Development
|
|
838
847
|
|
|
839
848
|
```bash
|
|
840
|
-
|
|
841
|
-
pytest tests/
|
|
849
|
+
uv sync
|
|
850
|
+
uv run pytest tests/
|
|
842
851
|
```
|
|
843
852
|
|
|
844
853
|
### Syncing with Remote
|
|
@@ -882,6 +891,20 @@ This project follows [Semantic Versioning](https://semver.org/) (MAJOR.MINOR.PAT
|
|
|
882
891
|
|
|
883
892
|
## Changelog
|
|
884
893
|
|
|
894
|
+
### 0.0.9 — 2026-10-09
|
|
895
|
+
|
|
896
|
+
- Dependency lower bound is now `sqlmodel>=0.0.27`. SQLModel 0.0.22–0.0.26 cannot create models on Python 3.14 (`Field 'id' requires a type annotation`), so the previous `>=0.0.22` bound was never satisfiable. Test suite passes on every SQLModel from 0.0.27 to 0.0.48.
|
|
897
|
+
- Removed the unused `dev` extra (`mypy`, `ruff>=0.8.0`) and `[tool.mypy]`: types are checked with `pyright`, dev tools live in `[dependency-groups]`. `pip install sqlmodel-object-helpers[dev]` no longer exists.
|
|
898
|
+
|
|
899
|
+
### 0.0.8 — 2026-10-09
|
|
900
|
+
|
|
901
|
+
- **SQLModel ≥0.0.45 support** — `build_dynamic_meta` maps an unmapped `TypeDecorator` by its `impl`, so bare `datetime` fields (`UTCDateTime` in SQLModel ≥0.0.45) stay `datetime` instead of falling back to `string`. `Interval` stays `string`. Tested on SQLModel 0.0.42 and 0.0.48. The `sqlmodel>=0.0.22` lower bound is unchanged.
|
|
902
|
+
- Dependency is now `sqlalchemy[asyncio]` — the package imports `sqlalchemy.ext.asyncio`, and SQLAlchemy 2.1 (allowed by SQLModel 0.0.48) no longer installs `greenlet` by default.
|
|
903
|
+
- **LogicalOperator** — `StrEnum` for `logical_operator`. An unknown value now raises `InvalidFilterError`; before, anything except `"AND"` silently meant OR. Plain strings `"AND"`/`"OR"` keep working.
|
|
904
|
+
- Typing: `get_object` / `get_objects` overloads narrow the return type by `columns`, `pagination` and `suspend_error`; the package and tests are clean under the fleet `pyright` config.
|
|
905
|
+
- Test dependencies moved to `[dependency-groups] dev` — `uv sync` installs them.
|
|
906
|
+
- Docs: [Datetime columns and SQLModel ≥0.0.45](#datetime-columns-and-sqlmodel-0045).
|
|
907
|
+
|
|
885
908
|
### 0.0.6
|
|
886
909
|
|
|
887
910
|
- **build_dynamic_meta** / **load_pg_comments** / **configure_meta_cache_ttl** / **invalidate_meta_cache** — dynamic UI metadata reader. Builds `TableMeta` and `list[ColumnMeta]` from a SQLModel class by reading PostgreSQL `pg_description` (TTL-cached, default 60s) with fallback to `Column(comment=...)` defaults from the model. Supports per-role label/row_link overrides via extended `||` comment format. For physical columns the label precedence is `pg_description` > `Column(comment=...)` model default. For virtual columns (paths with `.` traversing relationships) and full overrides — pass a fully-specified `ColumnMeta` instance directly in the `columns` list (used as-is, no derivation). Lookup `lookup_dict`/`lookup_path` are derived from FK on `*_lkp` tables by `{schema}_{base}` convention. Type derived from SA column type. DBAs can edit labels via `COMMENT ON COLUMN/TABLE` SQL — frontend reflects changes within cache TTL without redeploy. No sync block, no schema migrations introduced; the application's `db.py` is not touched.
|
|
@@ -261,7 +261,7 @@ result = await soh.get_objects(
|
|
|
261
261
|
users = await soh.get_objects(
|
|
262
262
|
session, User,
|
|
263
263
|
filters={"is_active": {soh.Operator.EQ: True}, "role": {soh.Operator.EQ: "admin"}},
|
|
264
|
-
logical_operator=
|
|
264
|
+
logical_operator=soh.LogicalOperator.OR,
|
|
265
265
|
)
|
|
266
266
|
|
|
267
267
|
# Relationship filters (dot-notation)
|
|
@@ -489,6 +489,8 @@ Used by `get_objects`. Nested dicts are auto-flattened via `flatten_filters`:
|
|
|
489
489
|
|
|
490
490
|
`Operator` is a `StrEnum` — each member equals its string value (`Operator.EQ == "eq"`), so string keys still work but enum members provide type safety and autocompletion.
|
|
491
491
|
|
|
492
|
+
`logical_operator` of `get_objects`, `count_objects`, `update_objects` and `delete_objects` takes `soh.LogicalOperator.AND` (default) or `soh.LogicalOperator.OR`; the strings `"AND"`/`"OR"` in any case still work. Any other value raises `InvalidFilterError`, even with `suspend_error=True`.
|
|
493
|
+
|
|
492
494
|
Multiple operators can be combined on a single field: `{"age": {soh.Operator.GE: 18, soh.Operator.LE: 65}}`.
|
|
493
495
|
|
|
494
496
|
### Typed Filter Models
|
|
@@ -535,6 +537,15 @@ Each date part accepts ISO (`2026-04-01`, `2026-04-01T00:00:00Z`) and display fo
|
|
|
535
537
|
- `FilterDatetimeRange` — produces UTC-aware datetimes
|
|
536
538
|
- `FilterNaiveDatetimeRange` — produces naive (timezone-unaware) datetimes
|
|
537
539
|
|
|
540
|
+
#### Datetime columns and SQLModel ≥0.0.45
|
|
541
|
+
|
|
542
|
+
Since SQLModel 0.0.45 a bare `datetime` field (no `sa_type` / `sa_column`) becomes `UTCDateTime` — `TIMESTAMP WITH TIME ZONE` that rejects naive values and returns UTC-aware ones. soh works on both sides of this change:
|
|
543
|
+
|
|
544
|
+
- Filter such columns with `FilterDatetime`, `FilterDatetimeRange`, `TimeFilter` or aware `datetime` values. A naive value is rejected by SQLModel and surfaces as `soh.DatabaseError`.
|
|
545
|
+
- `FilterNaiveDatetime` / `FilterNaiveDatetimeRange` are for columns declared explicitly as naive: `sa_type=DateTime` or `sa_column=Column(DateTime())`.
|
|
546
|
+
- `build_dynamic_meta` reports `UTCDateTime` columns as `datetime`.
|
|
547
|
+
- SQLModel does not migrate existing database columns. Over an existing `timestamp` column a bare `datetime` field reads values as UTC and, when the PostgreSQL session `TimeZone` is not UTC, writes them shifted by its offset. To keep the current behaviour of a bare `datetime` field, declare its database type explicitly: `sa_column=Column(DateTime())` for `timestamp`, `sa_column=Column(DateTime(timezone=True))` for `timestamptz`.
|
|
548
|
+
|
|
538
549
|
## Eager Loading
|
|
539
550
|
|
|
540
551
|
The library automatically selects the optimal loading strategy:
|
|
@@ -632,8 +643,11 @@ Physical column types are mapped automatically. Unknown types fall back to `stri
|
|
|
632
643
|
| `Integer`, `BigInteger`, `SmallInteger` | `integer` |
|
|
633
644
|
| `Numeric`, `Float` | `float` |
|
|
634
645
|
| `String`, `Text`, `Enum`, `Interval`, `ARRAY`, `Uuid` | `string` |
|
|
646
|
+
| Unmapped `TypeDecorator` (e.g. SQLModel `UTCDateTime`) | type of its `impl` |
|
|
635
647
|
| Any other type | `string` (fallback) |
|
|
636
648
|
|
|
649
|
+
`Interval` is a `TypeDecorator` over `DateTime`, but its own entry wins, so it stays `string`.
|
|
650
|
+
|
|
637
651
|
### Label precedence (per physical column)
|
|
638
652
|
|
|
639
653
|
1. `pg_description` — DBA edit via `COMMENT ON COLUMN` (supports per-role `||` overrides)
|
|
@@ -749,6 +763,7 @@ Endpoints can be migrated one at a time. Three strategies per endpoint:
|
|
|
749
763
|
### Operators
|
|
750
764
|
|
|
751
765
|
- `soh.Operator` -- StrEnum of operator names
|
|
766
|
+
- `soh.LogicalOperator` -- StrEnum `AND`/`OR` for the `logical_operator` argument
|
|
752
767
|
- `soh.SUPPORTED_OPERATORS` -- Dict mapping operator names to SQLAlchemy lambdas
|
|
753
768
|
- `soh.SPECIAL_OPERATORS` -- Frozenset of operators with extended handling (`{"exists"}`)
|
|
754
769
|
|
|
@@ -803,8 +818,8 @@ Endpoints can be migrated one at a time. Three strategies per endpoint:
|
|
|
803
818
|
## Development
|
|
804
819
|
|
|
805
820
|
```bash
|
|
806
|
-
|
|
807
|
-
pytest tests/
|
|
821
|
+
uv sync
|
|
822
|
+
uv run pytest tests/
|
|
808
823
|
```
|
|
809
824
|
|
|
810
825
|
### Syncing with Remote
|
|
@@ -848,6 +863,20 @@ This project follows [Semantic Versioning](https://semver.org/) (MAJOR.MINOR.PAT
|
|
|
848
863
|
|
|
849
864
|
## Changelog
|
|
850
865
|
|
|
866
|
+
### 0.0.9 — 2026-10-09
|
|
867
|
+
|
|
868
|
+
- Dependency lower bound is now `sqlmodel>=0.0.27`. SQLModel 0.0.22–0.0.26 cannot create models on Python 3.14 (`Field 'id' requires a type annotation`), so the previous `>=0.0.22` bound was never satisfiable. Test suite passes on every SQLModel from 0.0.27 to 0.0.48.
|
|
869
|
+
- Removed the unused `dev` extra (`mypy`, `ruff>=0.8.0`) and `[tool.mypy]`: types are checked with `pyright`, dev tools live in `[dependency-groups]`. `pip install sqlmodel-object-helpers[dev]` no longer exists.
|
|
870
|
+
|
|
871
|
+
### 0.0.8 — 2026-10-09
|
|
872
|
+
|
|
873
|
+
- **SQLModel ≥0.0.45 support** — `build_dynamic_meta` maps an unmapped `TypeDecorator` by its `impl`, so bare `datetime` fields (`UTCDateTime` in SQLModel ≥0.0.45) stay `datetime` instead of falling back to `string`. `Interval` stays `string`. Tested on SQLModel 0.0.42 and 0.0.48. The `sqlmodel>=0.0.22` lower bound is unchanged.
|
|
874
|
+
- Dependency is now `sqlalchemy[asyncio]` — the package imports `sqlalchemy.ext.asyncio`, and SQLAlchemy 2.1 (allowed by SQLModel 0.0.48) no longer installs `greenlet` by default.
|
|
875
|
+
- **LogicalOperator** — `StrEnum` for `logical_operator`. An unknown value now raises `InvalidFilterError`; before, anything except `"AND"` silently meant OR. Plain strings `"AND"`/`"OR"` keep working.
|
|
876
|
+
- Typing: `get_object` / `get_objects` overloads narrow the return type by `columns`, `pagination` and `suspend_error`; the package and tests are clean under the fleet `pyright` config.
|
|
877
|
+
- Test dependencies moved to `[dependency-groups] dev` — `uv sync` installs them.
|
|
878
|
+
- Docs: [Datetime columns and SQLModel ≥0.0.45](#datetime-columns-and-sqlmodel-0045).
|
|
879
|
+
|
|
851
880
|
### 0.0.6
|
|
852
881
|
|
|
853
882
|
- **build_dynamic_meta** / **load_pg_comments** / **configure_meta_cache_ttl** / **invalidate_meta_cache** — dynamic UI metadata reader. Builds `TableMeta` and `list[ColumnMeta]` from a SQLModel class by reading PostgreSQL `pg_description` (TTL-cached, default 60s) with fallback to `Column(comment=...)` defaults from the model. Supports per-role label/row_link overrides via extended `||` comment format. For physical columns the label precedence is `pg_description` > `Column(comment=...)` model default. For virtual columns (paths with `.` traversing relationships) and full overrides — pass a fully-specified `ColumnMeta` instance directly in the `columns` list (used as-is, no derivation). Lookup `lookup_dict`/`lookup_path` are derived from FK on `*_lkp` tables by `{schema}_{base}` convention. Type derived from SA column type. DBAs can edit labels via `COMMENT ON COLUMN/TABLE` SQL — frontend reflects changes within cache TTL without redeploy. No sync block, no schema migrations introduced; the application's `db.py` is not touched.
|
|
@@ -26,8 +26,8 @@ classifiers = [
|
|
|
26
26
|
"Typing :: Typed",
|
|
27
27
|
]
|
|
28
28
|
dependencies = [
|
|
29
|
-
"sqlmodel>=0.0.
|
|
30
|
-
"sqlalchemy>=2.0.46",
|
|
29
|
+
"sqlmodel>=0.0.27",
|
|
30
|
+
"sqlalchemy[asyncio]>=2.0.46",
|
|
31
31
|
"pydantic>=2.12",
|
|
32
32
|
]
|
|
33
33
|
|
|
@@ -37,28 +37,18 @@ Repository = "https://github.com/itstandart/sqlmodel-object-helpers"
|
|
|
37
37
|
Documentation = "https://github.com/itstandart/sqlmodel-object-helpers#readme"
|
|
38
38
|
Issues = "https://github.com/itstandart/sqlmodel-object-helpers/issues"
|
|
39
39
|
|
|
40
|
-
[project.optional-dependencies]
|
|
41
|
-
dev = [
|
|
42
|
-
"pytest>=7.0",
|
|
43
|
-
"pytest-asyncio>=0.21",
|
|
44
|
-
"aiosqlite>=0.20",
|
|
45
|
-
"ruff>=0.8.0",
|
|
46
|
-
"mypy>=1.13.0",
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
[tool.ruff]
|
|
50
|
-
target-version = "py314"
|
|
51
|
-
line-length = 120
|
|
52
|
-
|
|
53
|
-
[tool.ruff.lint]
|
|
54
|
-
select = ["E", "F", "W", "I", "UP", "B", "SIM", "PTH"]
|
|
55
|
-
|
|
56
|
-
[tool.mypy]
|
|
57
|
-
python_version = "3.14"
|
|
58
|
-
strict = true
|
|
59
|
-
|
|
60
40
|
[tool.hatch.version]
|
|
61
41
|
path = "src/sqlmodel_object_helpers/__init__.py"
|
|
62
42
|
|
|
63
43
|
[tool.hatch.build.targets.wheel]
|
|
64
44
|
packages = ["src/sqlmodel_object_helpers"]
|
|
45
|
+
|
|
46
|
+
[dependency-groups]
|
|
47
|
+
dev = [
|
|
48
|
+
"ruff==0.16.10",
|
|
49
|
+
"pyright==1.1.414",
|
|
50
|
+
"tzdata==2026.5",
|
|
51
|
+
"pytest==9.1.1",
|
|
52
|
+
"pytest-asyncio==1.4.0",
|
|
53
|
+
"aiosqlite==0.22.1",
|
|
54
|
+
]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Общий стандарт python-парка. Проверка типов.
|
|
3
|
+
// Источник: devops/ci-templates/standards/pyrightconfig.json @ v1.11.0
|
|
4
|
+
//
|
|
5
|
+
// Файл одинаков во всех репозиториях и правится ТОЛЬКО в devops/ci-templates.
|
|
6
|
+
// Джоба standards_check сверяет его sha256 и упадёт на любой локальной правке.
|
|
7
|
+
//
|
|
8
|
+
// Локальное исключение — комментарий рядом с кодом:
|
|
9
|
+
// value = obj.attr # pyright: ignore[reportAttributeAccessIssue] причина
|
|
10
|
+
// Если исключение общее для парка — оно едет сюда, а не в проект.
|
|
11
|
+
|
|
12
|
+
// Без этих двух ключей pyright не находит виртуальное окружение uv и считает
|
|
13
|
+
// ненайденным КАЖДЫЙ сторонний импорт: на канарейке это давало 32 ложных
|
|
14
|
+
// reportMissingImports из 47 ошибок.
|
|
15
|
+
"venvPath": ".",
|
|
16
|
+
"venv": ".venv",
|
|
17
|
+
|
|
18
|
+
// pythonVersion намеренно не задан: pyright берёт версию из интерпретатора
|
|
19
|
+
// в .venv, то есть из requires-python конкретного репозитория.
|
|
20
|
+
|
|
21
|
+
// standard — текущий режим pyright по умолчанию. На парке практически
|
|
22
|
+
// не отличается от устаревшего basic (16 против 17 ошибок на канарейке),
|
|
23
|
+
// а strict нереалистичен (297 на той же канарейке).
|
|
24
|
+
"typeCheckingMode": "standard",
|
|
25
|
+
|
|
26
|
+
// "**/.*" — это умолчание самого pyright, и его обязательно повторить здесь:
|
|
27
|
+
// задавая свой exclude, мы умолчание ЗАМЕНЯЕМ, а не дополняем. Без этой
|
|
28
|
+
// строки pyright заходит в скрытые каталоги, и у sro-agent-core, где
|
|
29
|
+
// [tool.uv] cache-dir = ".uv-cache" держит кеш пакетов ВНУТРИ репозитория,
|
|
30
|
+
// он анализировал ещё и распакованные колёса: джоба упиралась в потолок
|
|
31
|
+
// раннера 600 с и не заканчивалась вовсе (пайплайны #8517 и #8518).
|
|
32
|
+
// Сюда же попадают .venv, .git, .ruff_cache, .pytest_cache.
|
|
33
|
+
"exclude": [
|
|
34
|
+
"**/.*",
|
|
35
|
+
"**/node_modules",
|
|
36
|
+
"**/__pycache__"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Общий стандарт python-парка. Линтер и форматтер.
|
|
2
|
+
# Источник: devops/ci-templates/standards/ruff.toml @ v1.25.0
|
|
3
|
+
#
|
|
4
|
+
# Файл одинаков во всех репозиториях и правится ТОЛЬКО в devops/ci-templates.
|
|
5
|
+
# Джоба standards_check сверяет его sha256 и упадёт на любой локальной правке.
|
|
6
|
+
#
|
|
7
|
+
# Локальное исключение — noqa рядом с кодом и с причиной:
|
|
8
|
+
# result = query.all() # noqa: S608 имя колонки только из whitelist
|
|
9
|
+
# # ruff: noqa: UP037 в шапке файла — на весь файл
|
|
10
|
+
# Правило PGH004 не даст поставить noqa без кодов, RUF100 снимет протухшие.
|
|
11
|
+
# Если исключение общее для парка — оно едет сюда, а не в проект.
|
|
12
|
+
|
|
13
|
+
line-length = 120
|
|
14
|
+
|
|
15
|
+
# target-version намеренно не задан: ruff берёт его из project.requires-python
|
|
16
|
+
# в pyproject.toml каждого репозитория (проверено — работает и когда конфиг
|
|
17
|
+
# лежит в отдельном ruff.toml). Так один общий файл остаётся корректным и для
|
|
18
|
+
# библиотеки, объявляющей поддержку более старого Python.
|
|
19
|
+
|
|
20
|
+
[lint]
|
|
21
|
+
select = [
|
|
22
|
+
# pycodestyle + pyflakes — база
|
|
23
|
+
"E", "W", "F",
|
|
24
|
+
# сортировка импортов
|
|
25
|
+
"I",
|
|
26
|
+
# современный синтаксис под target-version
|
|
27
|
+
"UP",
|
|
28
|
+
# типовые дефекты и упрощения
|
|
29
|
+
"B", "SIM", "RET", "C4", "PIE", "PERF", "FURB",
|
|
30
|
+
# сложность функций, порог в [lint.mccabe]
|
|
31
|
+
"C901",
|
|
32
|
+
# pathlib вместо os.path
|
|
33
|
+
"PTH",
|
|
34
|
+
# безопасность (bandit)
|
|
35
|
+
"S",
|
|
36
|
+
# datetime без таймзоны
|
|
37
|
+
"DTZ",
|
|
38
|
+
# логирование
|
|
39
|
+
"LOG", "G",
|
|
40
|
+
# забытый print/pprint
|
|
41
|
+
"T20",
|
|
42
|
+
# корректность async
|
|
43
|
+
"ASYNC",
|
|
44
|
+
# except без типа
|
|
45
|
+
"BLE",
|
|
46
|
+
"INT", "YTT",
|
|
47
|
+
# RUF100 — протухшие noqa
|
|
48
|
+
"RUF",
|
|
49
|
+
# PGH004 — noqa обязан быть с кодами
|
|
50
|
+
"PGH",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
ignore = [
|
|
54
|
+
# --- Конфликтуют с ruff format, держать выключенными ---
|
|
55
|
+
# (длину строки контролирует форматтер, отступы и табы — тоже)
|
|
56
|
+
"E501", "W191", "E101",
|
|
57
|
+
|
|
58
|
+
# --- Кириллица ---
|
|
59
|
+
# RUF001-003 считают кириллические буквы «двусмысленными» из-за похожих
|
|
60
|
+
# латинских. Для русскоязычного кода это сплошной шум: 2542 находки из 4690
|
|
61
|
+
# по парку на момент введения стандарта.
|
|
62
|
+
"RUF001", "RUF002", "RUF003",
|
|
63
|
+
|
|
64
|
+
# --- Порядок импортов ---
|
|
65
|
+
# settings и логгер поднимаются до импорта приложения — это осознанный
|
|
66
|
+
# порядок инициализации, а не небрежность.
|
|
67
|
+
"E402",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[lint.mccabe]
|
|
71
|
+
# C901 — единственное измерение, которого в стандарте не было: ветвистость
|
|
72
|
+
# функции ruff до сих пор не мерил вовсе, и её замечал только человек на ревью.
|
|
73
|
+
#
|
|
74
|
+
# Порог 15, а не дефолтные 10. На 10 в exam-crm-core 70 функций, в
|
|
75
|
+
# sro-agent-core 17 — это фон, а не список к работе. На 15 остаётся 32 и 4,
|
|
76
|
+
# и это ровно те места, куда никто не хочет лезть: migrate_fias_addresses (46),
|
|
77
|
+
# recalculate_payments_new_with_session (45), set_block (44), get_objects (42)
|
|
78
|
+
# в легаси-монолите exam-crm и sa_core_compiler.compile (21) в ядре sro-agent.
|
|
79
|
+
#
|
|
80
|
+
# Правило неблокирующее: ruff_lint идёт с allow_failure, а Code Quality в MR
|
|
81
|
+
# показывает находки только на изменённых строках. То есть порог сторожит
|
|
82
|
+
# НОВЫЕ сложные функции, а не требует переписать легаси. Понижать по мере
|
|
83
|
+
# разбора, отдельными релизами.
|
|
84
|
+
#
|
|
85
|
+
# В per-file-ignores для тестов C901 не нужен: на пороге 15 в **/tests/**
|
|
86
|
+
# обоих ядер ноль находок (проверено до введения правила).
|
|
87
|
+
max-complexity = 15
|
|
88
|
+
|
|
89
|
+
[lint.per-file-ignores]
|
|
90
|
+
# Шаблон именно **/tests/**, а не tests/**: у exam-crm-core тесты лежат
|
|
91
|
+
# в app/tests/, и корневой шаблон бы их не поймал.
|
|
92
|
+
"**/tests/**" = [
|
|
93
|
+
# assert — это и есть тест
|
|
94
|
+
"S101",
|
|
95
|
+
# white-box-доступ к приватным атрибутам проверяемого объекта
|
|
96
|
+
"SLF001",
|
|
97
|
+
# магические значения в ожиданиях
|
|
98
|
+
"PLR2004",
|
|
99
|
+
# неиспользуемые аргументы фикстур и фейков, реализующих Protocol
|
|
100
|
+
"ARG",
|
|
101
|
+
# ленивые импорты внутри фикстур
|
|
102
|
+
"PLC0415",
|
|
103
|
+
# составные assert
|
|
104
|
+
"PT018",
|
|
105
|
+
# тестовым пакетам __init__.py не нужен
|
|
106
|
+
"INP001",
|
|
107
|
+
# пароли и токены в фикстурах — синтетика
|
|
108
|
+
"S105", "S106",
|
|
109
|
+
# naive datetime в ожиданиях
|
|
110
|
+
"DTZ001",
|
|
111
|
+
# __enter__ у тест-дублей возвращает self
|
|
112
|
+
"PYI034",
|
|
113
|
+
# bool-параметры в parametrize
|
|
114
|
+
"FBT001", "FBT002",
|
|
115
|
+
# закомментированный код в ожидаемых значениях
|
|
116
|
+
"ERA001",
|
|
117
|
+
# диагностический print
|
|
118
|
+
"T20",
|
|
119
|
+
# широкий except в проверках устойчивости
|
|
120
|
+
"BLE001",
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
[format]
|
|
124
|
+
# ruff format умеет форматировать python-блоки внутри markdown, и по умолчанию
|
|
125
|
+
# это включено. В парке 36 файлов .md с такими блоками (17 в exam-crm-core,
|
|
126
|
+
# 11 в sro-agent-core): формат переписал бы примеры в документации, а
|
|
127
|
+
# ruff format --check краснел бы на сокращённых и псевдокодовых сниппетах.
|
|
128
|
+
# Стандарт касается кода, а не документации.
|
|
129
|
+
exclude = ["*.md"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""sqlmodel-object-helpers — reusable query helpers for SQLModel projects."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.0.
|
|
3
|
+
__version__ = "0.0.9"
|
|
4
4
|
|
|
5
5
|
from .constants import QueryHelperSettings, settings
|
|
6
6
|
from .dynamic_meta import (
|
|
@@ -29,7 +29,7 @@ from .mutations import (
|
|
|
29
29
|
update_object,
|
|
30
30
|
update_objects,
|
|
31
31
|
)
|
|
32
|
-
from .operators import SPECIAL_OPERATORS, SUPPORTED_OPERATORS, Operator
|
|
32
|
+
from .operators import SPECIAL_OPERATORS, SUPPORTED_OPERATORS, LogicalOperator, Operator
|
|
33
33
|
from .query import count_objects, exists_object, get_object, get_objects, get_projection
|
|
34
34
|
from .session import auto_session, configure, create_session_dependency
|
|
35
35
|
from .types.columns import BoolLabels, ColumnMeta, ColumnType, TableMeta
|
|
@@ -61,28 +61,14 @@ from .types.pagination import (
|
|
|
61
61
|
from .types.projections import ColumnSpec
|
|
62
62
|
|
|
63
63
|
__all__ = [
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"auto_session",
|
|
67
|
-
"build_dynamic_meta",
|
|
68
|
-
"build_filter",
|
|
69
|
-
"build_flat_filter",
|
|
70
|
-
"build_load_chain",
|
|
71
|
-
"build_load_options",
|
|
72
|
-
"check_for_related_records",
|
|
64
|
+
"SPECIAL_OPERATORS",
|
|
65
|
+
"SUPPORTED_OPERATORS",
|
|
73
66
|
"BoolLabels",
|
|
74
67
|
"ColumnEntry",
|
|
75
68
|
"ColumnMeta",
|
|
76
69
|
"ColumnSpec",
|
|
77
70
|
"ColumnType",
|
|
78
|
-
"configure",
|
|
79
|
-
"configure_meta_cache_ttl",
|
|
80
|
-
"count_objects",
|
|
81
|
-
"create_session_dependency",
|
|
82
71
|
"DatabaseError",
|
|
83
|
-
"delete_object",
|
|
84
|
-
"delete_objects",
|
|
85
|
-
"exists_object",
|
|
86
72
|
"FilterBool",
|
|
87
73
|
"FilterDate",
|
|
88
74
|
"FilterDatetime",
|
|
@@ -93,16 +79,11 @@ __all__ = [
|
|
|
93
79
|
"FilterNaiveDatetimeRange",
|
|
94
80
|
"FilterStr",
|
|
95
81
|
"FilterTimedelta",
|
|
96
|
-
"flatten_filters",
|
|
97
|
-
"get_object",
|
|
98
|
-
"get_objects",
|
|
99
|
-
"get_projection",
|
|
100
82
|
"GetAllPagination",
|
|
101
|
-
"invalidate_meta_cache",
|
|
102
83
|
"InvalidFilterError",
|
|
103
84
|
"InvalidLoadPathError",
|
|
104
|
-
"load_pg_comments",
|
|
105
85
|
"LogicalFilter",
|
|
86
|
+
"LogicalOperator",
|
|
106
87
|
"LookupMeta",
|
|
107
88
|
"LookupResponse",
|
|
108
89
|
"MutationError",
|
|
@@ -115,12 +96,32 @@ __all__ = [
|
|
|
115
96
|
"PaginationR",
|
|
116
97
|
"QueryError",
|
|
117
98
|
"QueryHelperSettings",
|
|
118
|
-
"settings",
|
|
119
|
-
"SPECIAL_OPERATORS",
|
|
120
|
-
"SUPPORTED_OPERATORS",
|
|
121
99
|
"TableMeta",
|
|
122
100
|
"TimeFilter",
|
|
101
|
+
"UTCDatetime",
|
|
102
|
+
"add_object",
|
|
103
|
+
"add_objects",
|
|
104
|
+
"auto_session",
|
|
105
|
+
"build_dynamic_meta",
|
|
106
|
+
"build_filter",
|
|
107
|
+
"build_flat_filter",
|
|
108
|
+
"build_load_chain",
|
|
109
|
+
"build_load_options",
|
|
110
|
+
"check_for_related_records",
|
|
111
|
+
"configure",
|
|
112
|
+
"configure_meta_cache_ttl",
|
|
113
|
+
"count_objects",
|
|
114
|
+
"create_session_dependency",
|
|
115
|
+
"delete_object",
|
|
116
|
+
"delete_objects",
|
|
117
|
+
"exists_object",
|
|
118
|
+
"flatten_filters",
|
|
119
|
+
"get_object",
|
|
120
|
+
"get_objects",
|
|
121
|
+
"get_projection",
|
|
122
|
+
"invalidate_meta_cache",
|
|
123
|
+
"load_pg_comments",
|
|
124
|
+
"settings",
|
|
123
125
|
"update_object",
|
|
124
126
|
"update_objects",
|
|
125
|
-
"UTCDatetime",
|
|
126
127
|
]
|