
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
from typing import (
|
|
Tuple,
|
|
TypeVar,
|
|
Union,
|
|
)
|
|
|
|
from sqlalchemy.sql._typing import (
|
|
_ColumnExpressionArgument,
|
|
)
|
|
from sqlalchemy.sql.expression import Select as _Select
|
|
from typing_extensions import Self
|
|
|
|
_T = TypeVar("_T")
|
|
|
|
|
|
# Separate this class in SelectBase, Select, and SelectOfScalar so that they can share
|
|
# where and having without having type overlap incompatibility in session.exec().
|
|
class SelectBase(_Select[Tuple[_T]]):
|
|
inherit_cache = True
|
|
|
|
def where(self, *whereclause: Union[_ColumnExpressionArgument[bool], bool]) -> Self:
|
|
"""Return a new `Select` construct with the given expression added to
|
|
its `WHERE` clause, joined to the existing clause via `AND`, if any.
|
|
"""
|
|
return super().where(*whereclause) # type: ignore[arg-type]
|
|
|
|
def having(self, *having: Union[_ColumnExpressionArgument[bool], bool]) -> Self:
|
|
"""Return a new `Select` construct with the given expression added to
|
|
its `HAVING` clause, joined to the existing clause via `AND`, if any.
|
|
"""
|
|
return super().having(*having) # type: ignore[arg-type]
|
|
|
|
|
|
class Select(SelectBase[_T]):
|
|
inherit_cache = True
|
|
|
|
|
|
# This is not comparable to sqlalchemy.sql.selectable.ScalarSelect, that has a different
|
|
# purpose. This is the same as a normal SQLAlchemy Select class where there's only one
|
|
# entity, so the result will be converted to a scalar by default. This way writing
|
|
# for loops on the results will feel natural.
|
|
class SelectOfScalar(SelectBase[_T]):
|
|
inherit_cache = True
|