Coverage for sqlmodel / sql / expression.py: 64%
64 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-01-06 21:09 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-01-06 21:09 +0000
1from collections.abc import Iterable, Mapping, Sequence 1abcdefghi
2from typing import ( 1abcdefghi
3 Any,
4 Optional,
5 TypeVar,
6 Union,
7)
9import sqlalchemy 1abcdefghi
10from sqlalchemy import ( 1abcdefghi
11 Column,
12 ColumnElement,
13 Extract,
14 FunctionElement,
15 FunctionFilter,
16 Label,
17 Over,
18 TypeCoerce,
19 WithinGroup,
20)
21from sqlalchemy.orm import InstrumentedAttribute, Mapped 1abcdefghi
22from sqlalchemy.sql._typing import ( 1abcdefghi
23 _ColumnExpressionArgument,
24 _ColumnExpressionOrLiteralArgument,
25 _ColumnExpressionOrStrLabelArgument,
26)
27from sqlalchemy.sql.elements import ( 1abcdefghi
28 BinaryExpression,
29 Case,
30 Cast,
31 CollectionAggregate,
32 ColumnClause,
33 TryCast,
34 UnaryExpression,
35)
36from sqlalchemy.sql.type_api import TypeEngine 1abcdefghi
37from typing_extensions import Literal 1abcdefghi
39from ._expression_select_cls import Select as Select 1abcdefghi
40from ._expression_select_cls import SelectOfScalar as SelectOfScalar 1abcdefghi
41from ._expression_select_gen import select as select 1abcdefghi
43_T = TypeVar("_T") 1abcdefghi
45_TypeEngineArgument = Union[type[TypeEngine[_T]], TypeEngine[_T]] 1abcdefghi
47# Redefine operatos that would only take a column expresion to also take the (virtual)
48# types of Pydantic models, e.g. str instead of only Mapped[str].
51def all_(expr: Union[_ColumnExpressionArgument[_T], _T]) -> CollectionAggregate[bool]: 1abcdefghi
52 return sqlalchemy.all_(expr) # type: ignore[arg-type]
55def and_( 1abcdefghi
56 initial_clause: Union[Literal[True], _ColumnExpressionArgument[bool], bool],
57 *clauses: Union[_ColumnExpressionArgument[bool], bool],
58) -> ColumnElement[bool]:
59 return sqlalchemy.and_(initial_clause, *clauses) # type: ignore[arg-type]
62def any_(expr: Union[_ColumnExpressionArgument[_T], _T]) -> CollectionAggregate[bool]: 1abcdefghi
63 return sqlalchemy.any_(expr) # type: ignore[arg-type]
66def asc( 1abcdefghi
67 column: Union[_ColumnExpressionOrStrLabelArgument[_T], _T],
68) -> UnaryExpression[_T]:
69 return sqlalchemy.asc(column) # type: ignore[arg-type]
72def collate( 1abcdefghi
73 expression: Union[_ColumnExpressionArgument[str], str], collation: str
74) -> BinaryExpression[str]:
75 return sqlalchemy.collate(expression, collation) # type: ignore[arg-type]
78def between( 1abcdefghi
79 expr: Union[_ColumnExpressionOrLiteralArgument[_T], _T],
80 lower_bound: Any,
81 upper_bound: Any,
82 symmetric: bool = False,
83) -> BinaryExpression[bool]:
84 return sqlalchemy.between(expr, lower_bound, upper_bound, symmetric=symmetric)
87def not_(clause: Union[_ColumnExpressionArgument[_T], _T]) -> ColumnElement[_T]: 1abcdefghi
88 return sqlalchemy.not_(clause) # type: ignore[arg-type]
91def case( 1abcdefghi
92 *whens: Union[
93 tuple[Union[_ColumnExpressionArgument[bool], bool], Any], Mapping[Any, Any]
94 ],
95 value: Optional[Any] = None,
96 else_: Optional[Any] = None,
97) -> Case[Any]:
98 return sqlalchemy.case(*whens, value=value, else_=else_) # type: ignore[arg-type]
101def cast( 1abcdefghi
102 expression: Union[_ColumnExpressionOrLiteralArgument[Any], Any],
103 type_: "_TypeEngineArgument[_T]",
104) -> Cast[_T]:
105 return sqlalchemy.cast(expression, type_)
108def try_cast( 1abcdefghi
109 expression: Union[_ColumnExpressionOrLiteralArgument[Any], Any],
110 type_: "_TypeEngineArgument[_T]",
111) -> TryCast[_T]:
112 return sqlalchemy.try_cast(expression, type_)
115def desc( 1abcdefghi
116 column: Union[_ColumnExpressionOrStrLabelArgument[_T], _T],
117) -> UnaryExpression[_T]:
118 return sqlalchemy.desc(column) # type: ignore[arg-type]
121def distinct(expr: Union[_ColumnExpressionArgument[_T], _T]) -> UnaryExpression[_T]: 1abcdefghi
122 return sqlalchemy.distinct(expr) # type: ignore[arg-type]
125def bitwise_not(expr: Union[_ColumnExpressionArgument[_T], _T]) -> UnaryExpression[_T]: 1abcdefghi
126 return sqlalchemy.bitwise_not(expr) # type: ignore[arg-type]
129def extract(field: str, expr: Union[_ColumnExpressionArgument[Any], Any]) -> Extract: 1abcdefghi
130 return sqlalchemy.extract(field, expr)
133def funcfilter( 1abcdefghi
134 func: FunctionElement[_T], *criterion: Union[_ColumnExpressionArgument[bool], bool]
135) -> FunctionFilter[_T]:
136 return sqlalchemy.funcfilter(func, *criterion) # type: ignore[arg-type]
139def label( 1abcdefghi
140 name: str,
141 element: Union[_ColumnExpressionArgument[_T], _T],
142 type_: Optional["_TypeEngineArgument[_T]"] = None,
143) -> Label[_T]:
144 return sqlalchemy.label(name, element, type_=type_) # type: ignore[arg-type]
147def nulls_first( 1abcdefghi
148 column: Union[_ColumnExpressionArgument[_T], _T],
149) -> UnaryExpression[_T]:
150 return sqlalchemy.nulls_first(column) # type: ignore[arg-type]
153def nulls_last(column: Union[_ColumnExpressionArgument[_T], _T]) -> UnaryExpression[_T]: 1abcdefghi
154 return sqlalchemy.nulls_last(column) # type: ignore[arg-type]
157def or_( 1abcdefghi
158 initial_clause: Union[Literal[False], _ColumnExpressionArgument[bool], bool],
159 *clauses: Union[_ColumnExpressionArgument[bool], bool],
160) -> ColumnElement[bool]:
161 return sqlalchemy.or_(initial_clause, *clauses) # type: ignore[arg-type] 1stuvwxyzA
164def over( 1abcdefghi
165 element: FunctionElement[_T],
166 partition_by: Optional[
167 Union[
168 Iterable[Union[_ColumnExpressionArgument[Any], Any]],
169 _ColumnExpressionArgument[Any],
170 Any,
171 ]
172 ] = None,
173 order_by: Optional[
174 Union[
175 Iterable[Union[_ColumnExpressionArgument[Any], Any]],
176 _ColumnExpressionArgument[Any],
177 Any,
178 ]
179 ] = None,
180 range_: Optional[tuple[Optional[int], Optional[int]]] = None,
181 rows: Optional[tuple[Optional[int], Optional[int]]] = None,
182) -> Over[_T]:
183 return sqlalchemy.over(
184 element, partition_by=partition_by, order_by=order_by, range_=range_, rows=rows
185 )
188def tuple_( 1abcdefghi
189 *clauses: Union[_ColumnExpressionArgument[Any], Any],
190 types: Optional[Sequence["_TypeEngineArgument[Any]"]] = None,
191) -> tuple[Any, ...]:
192 return sqlalchemy.tuple_(*clauses, types=types) # type: ignore[return-value]
195def type_coerce( 1abcdefghi
196 expression: Union[_ColumnExpressionOrLiteralArgument[Any], Any],
197 type_: "_TypeEngineArgument[_T]",
198) -> TypeCoerce[_T]:
199 return sqlalchemy.type_coerce(expression, type_)
202def within_group( 1abcdefghi
203 element: FunctionElement[_T], *order_by: Union[_ColumnExpressionArgument[Any], Any]
204) -> WithinGroup[_T]:
205 return sqlalchemy.within_group(element, *order_by)
208def col(column_expression: _T) -> Mapped[_T]: 1abcdefghi
209 if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)): 1jklmnopqr
210 raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
211 return column_expression # type: ignore 1jklmnopqr