fastapi-sqlalchemy-toolkit 0.7.20__tar.gz → 0.8.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.
Files changed (60) hide show
  1. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/PKG-INFO +1 -1
  2. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/fastapi_sqlalchemy_toolkit/model_manager.py +205 -12
  3. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/pyproject.toml +1 -1
  4. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/.flake8 +0 -0
  5. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/.github/workflows/docker-test.yml +0 -0
  6. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/.github/workflows/python-publish.yml +0 -0
  7. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/.gitignore +0 -0
  8. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/.pylintrc +0 -0
  9. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/AUTHORS +0 -0
  10. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/LICENSE +0 -0
  11. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/Makefile +0 -0
  12. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/README.md +0 -0
  13. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/benefits.md +0 -0
  14. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/db_validation.md +0 -0
  15. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/extension.md +0 -0
  16. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/filtering.md +0 -0
  17. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/index.md +0 -0
  18. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/benefits.md +0 -0
  19. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/db_validation.md +0 -0
  20. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/extension.md +0 -0
  21. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/filtering.md +0 -0
  22. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/index.md +0 -0
  23. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/sorting.md +0 -0
  24. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/transactions.md +0 -0
  25. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/usage.md +0 -0
  26. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/ru/utils.md +0 -0
  27. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/sorting.md +0 -0
  28. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/transactions.md +0 -0
  29. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/usage.md +0 -0
  30. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/docs/utils.md +0 -0
  31. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/.env +0 -0
  32. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/__init__.py +0 -0
  33. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/api/__init__.py +0 -0
  34. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/api/api.py +0 -0
  35. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/api/deps.py +0 -0
  36. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/api/endpoints/__init__.py +0 -0
  37. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/api/endpoints/child.py +0 -0
  38. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/config.py +0 -0
  39. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/db.py +0 -0
  40. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/main.py +0 -0
  41. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/managers.py +0 -0
  42. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/models.py +0 -0
  43. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/examples/app/schemas.py +0 -0
  44. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/fastapi_sqlalchemy_toolkit/__init__.py +0 -0
  45. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/fastapi_sqlalchemy_toolkit/filters.py +0 -0
  46. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/fastapi_sqlalchemy_toolkit/ordering.py +0 -0
  47. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/fastapi_sqlalchemy_toolkit/utils.py +0 -0
  48. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/mkdocs.yml +0 -0
  49. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/poetry.lock +0 -0
  50. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/requirements/base.txt +0 -0
  51. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/requirements/docs.txt +0 -0
  52. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/requirements/lint.txt +0 -0
  53. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/requirements/test.txt +0 -0
  54. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/Dockerfile +0 -0
  55. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/__init__.py +0 -0
  56. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/conftest.py +0 -0
  57. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/db.py +0 -0
  58. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/docker-compose.yml +0 -0
  59. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/models.py +0 -0
  60. {fastapi_sqlalchemy_toolkit-0.7.20 → fastapi_sqlalchemy_toolkit-0.8.1}/tests/test_public_methods.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi_sqlalchemy_toolkit
3
- Version: 0.7.20
3
+ Version: 0.8.1
4
4
  Summary: FastAPI SQLAlchemy Toolkit
5
5
  Project-URL: Homepage, https://github.com/e-kondr01/fastapi-sqlalchemy-toolkit
6
6
  Author-email: Egor Kondrashov <e.kondr01@gmail.com>
@@ -1,6 +1,6 @@
1
1
  # ruff: noqa: UP006
2
2
  from collections.abc import Callable, Iterable
3
- from typing import Any, Generic, List, TypeVar # noqa: UP035
3
+ from typing import Any, Generic, List, TypeVar, overload # noqa: UP035
4
4
 
5
5
  from fastapi import HTTPException, status
6
6
  from fastapi_pagination.bases import BasePage
@@ -26,6 +26,7 @@ from sqlalchemy.orm.attributes import InstrumentedAttribute
26
26
  from sqlalchemy.orm.relationships import Relationship
27
27
  from sqlalchemy.sql import Select
28
28
  from sqlalchemy.sql.elements import UnaryExpression
29
+ from sqlalchemy.sql.expression import BinaryExpression, ColumnElement
29
30
  from sqlalchemy.sql.functions import Function
30
31
  from sqlalchemy.sql.schema import ScalarElementColumnDefault
31
32
  from sqlalchemy.sql.selectable import Exists
@@ -234,6 +235,32 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
234
235
  return result.scalars().all()
235
236
  return None
236
237
 
238
+ @overload
239
+ async def get(
240
+ self,
241
+ session: AsyncSession,
242
+ options: List[Any] | Any | None = ...,
243
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
244
+ where: Any | None = ...,
245
+ base_stmt: None = ...,
246
+ *,
247
+ unique: bool = ...,
248
+ **simple_filters: Any,
249
+ ) -> ModelT | None: ...
250
+
251
+ @overload
252
+ async def get(
253
+ self,
254
+ session: AsyncSession,
255
+ options: List[Any] | Any | None = ...,
256
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
257
+ where: Any | None = ...,
258
+ base_stmt: Select = ...,
259
+ *,
260
+ unique: bool = ...,
261
+ **simple_filters: Any,
262
+ ) -> Row | None: ...
263
+
237
264
  async def get(
238
265
  self,
239
266
  session: AsyncSession,
@@ -280,6 +307,32 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
280
307
  return result.scalar_one_or_none()
281
308
  return result.first()
282
309
 
310
+ @overload
311
+ async def get_or_404(
312
+ self,
313
+ session: AsyncSession,
314
+ options: List[Any] | Any | None = ...,
315
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
316
+ where: Any | None = ...,
317
+ base_stmt: None = ...,
318
+ *,
319
+ unique: bool = ...,
320
+ **simple_filters: Any,
321
+ ) -> ModelT: ...
322
+
323
+ @overload
324
+ async def get_or_404(
325
+ self,
326
+ session: AsyncSession,
327
+ options: List[Any] | Any | None = ...,
328
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
329
+ where: Any | None = ...,
330
+ base_stmt: Select = ...,
331
+ *,
332
+ unique: bool = ...,
333
+ **simple_filters: Any,
334
+ ) -> Row: ...
335
+
283
336
  async def get_or_404(
284
337
  self,
285
338
  session: AsyncSession,
@@ -407,6 +460,30 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
407
460
  )
408
461
  return True
409
462
 
463
+ @overload
464
+ async def paginated_filter(
465
+ self,
466
+ session: AsyncSession,
467
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
468
+ options: List[Any] | Any | None = ...,
469
+ where: Any | None = ...,
470
+ base_stmt: None = ...,
471
+ transformer: Callable | None = ...,
472
+ **simple_filters: Any,
473
+ ) -> BasePage[ModelT]: ...
474
+
475
+ @overload
476
+ async def paginated_filter(
477
+ self,
478
+ session: AsyncSession,
479
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
480
+ options: List[Any] | Any | None = ...,
481
+ where: Any | None = ...,
482
+ base_stmt: Select = ...,
483
+ transformer: Callable | None = ...,
484
+ **simple_filters: Any,
485
+ ) -> BasePage[Row]: ...
486
+
410
487
  async def paginated_filter(
411
488
  self,
412
489
  session: AsyncSession,
@@ -416,7 +493,7 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
416
493
  base_stmt: Select | None = None,
417
494
  transformer: Callable | None = None,
418
495
  **simple_filters: Any,
419
- ) -> BasePage[ModelT | Row]:
496
+ ) -> BasePage[Any]:
420
497
  """
421
498
  Получение списка объектов с фильтрами и пагинацией.
422
499
 
@@ -443,11 +520,46 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
443
520
  stmt = self.assemble_stmt(base_stmt, order_by, options, where, **simple_filters)
444
521
  return await paginate(session, stmt, transformer=transformer)
445
522
 
523
+ @overload
524
+ async def paginated_list(
525
+ self,
526
+ session: AsyncSession,
527
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
528
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any]
529
+ | None = ...,
530
+ nullable_filter_expressions: (
531
+ dict[InstrumentedAttribute | Callable, Any] | None
532
+ ) = ...,
533
+ options: List[Any] | Any | None = ...,
534
+ where: Any | None = ...,
535
+ base_stmt: None = ...,
536
+ transformer: Callable | None = ...,
537
+ **simple_filters: Any,
538
+ ) -> BasePage[ModelT]: ...
539
+
540
+ @overload
541
+ async def paginated_list(
542
+ self,
543
+ session: AsyncSession,
544
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
545
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any]
546
+ | None = ...,
547
+ nullable_filter_expressions: (
548
+ dict[InstrumentedAttribute | Callable, Any] | None
549
+ ) = ...,
550
+ options: List[Any] | Any | None = ...,
551
+ where: Any | None = ...,
552
+ base_stmt: Select = ...,
553
+ transformer: Callable | None = ...,
554
+ **simple_filters: Any,
555
+ ) -> BasePage[Row]: ...
556
+
446
557
  async def paginated_list(
447
558
  self,
448
559
  session: AsyncSession,
449
560
  order_by: InstrumentedAttribute | UnaryExpression | None = None,
450
- filter_expressions: dict[InstrumentedAttribute | Callable, Any] | None = None,
561
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any]
562
+ | None = None,
451
563
  nullable_filter_expressions: (
452
564
  dict[InstrumentedAttribute | Callable, Any] | None
453
565
  ) = None,
@@ -456,7 +568,7 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
456
568
  base_stmt: Select | None = None,
457
569
  transformer: Callable | None = None,
458
570
  **simple_filters: Any,
459
- ) -> BasePage[ModelT | Row]:
571
+ ) -> BasePage[Any]:
460
572
  """
461
573
  Получение списка объектов с фильтрами и пагинацией.
462
574
  Пропускает фильтры, значения которых None.
@@ -510,13 +622,46 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
510
622
  )
511
623
 
512
624
  for filter_expression, value in filter_expressions.items():
513
- if isinstance(filter_expression, InstrumentedAttribute | Function):
625
+ if isinstance(
626
+ filter_expression,
627
+ InstrumentedAttribute | Function | BinaryExpression | ColumnElement,
628
+ ):
514
629
  stmt = stmt.filter(filter_expression == value)
515
630
  else:
516
631
  stmt = stmt.filter(filter_expression(value))
517
632
 
518
633
  return await paginate(session, stmt, transformer=transformer)
519
634
 
635
+ @overload
636
+ async def filter(
637
+ self,
638
+ session: AsyncSession,
639
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
640
+ options: List[Any] | Any | None = ...,
641
+ where: Any | None = ...,
642
+ base_stmt: None = ...,
643
+ limit: int | None = ...,
644
+ offset: int | None = ...,
645
+ *,
646
+ unique: bool = ...,
647
+ **simple_filters: Any,
648
+ ) -> List[ModelT]: ...
649
+
650
+ @overload
651
+ async def filter(
652
+ self,
653
+ session: AsyncSession,
654
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
655
+ options: List[Any] | Any | None = ...,
656
+ where: Any | None = ...,
657
+ base_stmt: Select = ...,
658
+ limit: int | None = ...,
659
+ offset: int | None = ...,
660
+ *,
661
+ unique: bool = ...,
662
+ **simple_filters: Any,
663
+ ) -> List[Row]: ...
664
+
520
665
  async def filter(
521
666
  self,
522
667
  session: AsyncSession,
@@ -529,7 +674,7 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
529
674
  *,
530
675
  unique: bool = False,
531
676
  **simple_filters: Any,
532
- ) -> List[ModelT] | List[Row]:
677
+ ) -> List[Any]:
533
678
  """
534
679
  Получение списка объектов с фильтрами
535
680
 
@@ -573,11 +718,52 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
573
718
  return result.scalars().all()
574
719
  return result.all()
575
720
 
721
+ @overload
722
+ async def list(
723
+ self,
724
+ session: AsyncSession,
725
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
726
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any]
727
+ | None = ...,
728
+ nullable_filter_expressions: (
729
+ dict[InstrumentedAttribute | Callable, Any] | None
730
+ ) = ...,
731
+ options: List[Any] | Any | None = ...,
732
+ where: Any | None = ...,
733
+ base_stmt: None = ...,
734
+ limit: int | None = ...,
735
+ offset: int | None = ...,
736
+ *,
737
+ unique: bool = ...,
738
+ **simple_filters: Any,
739
+ ) -> List[ModelT]: ...
740
+
741
+ @overload
742
+ async def list(
743
+ self,
744
+ session: AsyncSession,
745
+ order_by: InstrumentedAttribute | UnaryExpression | None = ...,
746
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any]
747
+ | None = ...,
748
+ nullable_filter_expressions: (
749
+ dict[InstrumentedAttribute | Callable, Any] | None
750
+ ) = ...,
751
+ options: List[Any] | Any | None = ...,
752
+ where: Any | None = ...,
753
+ base_stmt: Select = ...,
754
+ limit: int | None = ...,
755
+ offset: int | None = ...,
756
+ *,
757
+ unique: bool = ...,
758
+ **simple_filters: Any,
759
+ ) -> List[Row]: ...
760
+
576
761
  async def list(
577
762
  self,
578
763
  session: AsyncSession,
579
764
  order_by: InstrumentedAttribute | UnaryExpression | None = None,
580
- filter_expressions: dict[InstrumentedAttribute | Callable, Any] | None = None,
765
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any]
766
+ | None = None,
581
767
  nullable_filter_expressions: (
582
768
  dict[InstrumentedAttribute | Callable, Any] | None
583
769
  ) = None,
@@ -589,7 +775,7 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
589
775
  *,
590
776
  unique: bool = False,
591
777
  **simple_filters: Any,
592
- ) -> List[ModelT] | List[Row]:
778
+ ) -> List[Any]:
593
779
  """
594
780
  Получение списка объектов с фильтрами.
595
781
  Пропускает фильтры, значения которых None.
@@ -654,7 +840,10 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
654
840
  )
655
841
 
656
842
  for filter_expression, value in filter_expressions.items():
657
- if isinstance(filter_expression, InstrumentedAttribute):
843
+ if isinstance(
844
+ filter_expression,
845
+ InstrumentedAttribute | BinaryExpression | ColumnElement,
846
+ ):
658
847
  stmt = stmt.filter(filter_expression == value)
659
848
  else:
660
849
  stmt = stmt.filter(filter_expression(value))
@@ -899,7 +1088,7 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
899
1088
  def get_joins(
900
1089
  self,
901
1090
  base_query: Select,
902
- filter_expressions: dict[InstrumentedAttribute | Callable, Any],
1091
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any],
903
1092
  options: List[Any] | None = None,
904
1093
  order_by: InstrumentedAttribute | UnaryExpression | None = None,
905
1094
  ) -> Select:
@@ -932,6 +1121,8 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
932
1121
  model = filter_expression.parent._identity_class
933
1122
  elif isinstance(filter_expression, Function):
934
1123
  model = filter_expression.entity_namespace
1124
+ elif isinstance(filter_expression, ColumnElement):
1125
+ model = self.model # Not supported
935
1126
  else:
936
1127
  model = filter_expression.__self__.parent._identity_class
937
1128
  if model != self.model:
@@ -981,7 +1172,7 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
981
1172
 
982
1173
  @staticmethod
983
1174
  def handle_filter_expressions(
984
- filter_expressions: dict[InstrumentedAttribute | Callable, Any],
1175
+ filter_expressions: dict[InstrumentedAttribute | Callable | ColumnElement, Any],
985
1176
  ) -> None:
986
1177
  for filter_expression, value in filter_expressions.copy().items():
987
1178
  if value is None:
@@ -993,7 +1184,9 @@ class ModelManager(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
993
1184
 
994
1185
  @staticmethod
995
1186
  def handle_nullable_filter_expressions(
996
- nullable_filter_expressions: dict[InstrumentedAttribute | Callable, Any],
1187
+ nullable_filter_expressions: dict[
1188
+ InstrumentedAttribute | Callable | ColumnElement, Any
1189
+ ],
997
1190
  ) -> None:
998
1191
  for filter_expression, value in nullable_filter_expressions.copy().items():
999
1192
  if value in null_query_values:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fastapi_sqlalchemy_toolkit"
7
- version = "0.7.20"
7
+ version = "0.8.1"
8
8
  authors = [
9
9
  { name="Egor Kondrashov", email="e.kondr01@gmail.com" },
10
10
  ]