diff options
Diffstat (limited to 'lib/sqlalchemy/sql/_typing.py')
-rw-r--r-- | lib/sqlalchemy/sql/_typing.py | 135 |
1 files changed, 120 insertions, 15 deletions
diff --git a/lib/sqlalchemy/sql/_typing.py b/lib/sqlalchemy/sql/_typing.py index a5da87802..0a72a93c5 100644 --- a/lib/sqlalchemy/sql/_typing.py +++ b/lib/sqlalchemy/sql/_typing.py @@ -1,7 +1,7 @@ from __future__ import annotations +import operator from typing import Any -from typing import Iterable from typing import Type from typing import TYPE_CHECKING from typing import TypeVar @@ -24,9 +24,16 @@ if TYPE_CHECKING: from .roles import FromClauseRole from .schema import DefaultGenerator from .schema import Sequence + from .selectable import Alias from .selectable import FromClause + from .selectable import Join from .selectable import NamedFromClause + from .selectable import ReturnsRows + from .selectable import Select + from .selectable import SelectBase + from .selectable import Subquery from .selectable import TableClause + from .sqltypes import TableValueType from .sqltypes import TupleType from .type_api import TypeEngine from ..util.typing import TypeGuard @@ -47,6 +54,14 @@ class _HasClauseElement(Protocol): # the coercions system is responsible for converting from XYZArgument to # XYZElement. +_TextCoercedExpressionArgument = Union[ + str, + "TextClause", + "ColumnElement[_T]", + _HasClauseElement, + roles.ExpressionElementRole[_T], +] + _ColumnsClauseArgument = Union[ Literal["*", 1], roles.ColumnsClauseRole, @@ -54,8 +69,31 @@ _ColumnsClauseArgument = Union[ Inspectable[_HasClauseElement], _HasClauseElement, ] +"""open-ended SELECT columns clause argument. + +Includes column expressions, tables, ORM mapped entities, a few literal values. + +This type is used for lists of columns / entities to be returned in result +sets; select(...), insert().returning(...), etc. + + +""" + +_ColumnExpressionArgument = Union[ + "ColumnElement[_T]", _HasClauseElement, roles.ExpressionElementRole[_T] +] +"""narrower "column expression" argument. + +This type is used for all the other "column" kinds of expressions that +typically represent a single SQL column expression, not a set of columns the +way a table or ORM entity does. + +This includes ColumnElement, or ORM-mapped attributes that will have a +`__clause_element__()` method, it also has the ExpressionElementRole +overall which brings in the TextClause object also. + +""" -_SelectIterable = Iterable[Union["ColumnElement[Any]", "TextClause"]] _FromClauseArgument = Union[ roles.FromClauseRole, @@ -63,28 +101,99 @@ _FromClauseArgument = Union[ Inspectable[_HasClauseElement], _HasClauseElement, ] +"""A FROM clause, like we would send to select().select_from(). -_ColumnExpressionArgument = Union[ - "ColumnElement[_T]", _HasClauseElement, roles.ExpressionElementRole[_T] +Also accommodates ORM entities and related constructs. + +""" + +_JoinTargetArgument = Union[_FromClauseArgument, roles.JoinTargetRole] +"""target for join() builds on _FromClauseArgument to include additional +join target roles such as those which come from the ORM. + +""" + +_OnClauseArgument = Union[_ColumnExpressionArgument[Any], roles.OnClauseRole] +"""target for an ON clause, includes additional roles such as those which +come from the ORM. + +""" + +_SelectStatementForCompoundArgument = Union[ + "SelectBase", roles.CompoundElementRole +] +"""SELECT statement acceptable by ``union()`` and other SQL set operations""" + +_DMLColumnArgument = Union[ + str, "ColumnClause[Any]", _HasClauseElement, roles.DMLColumnRole ] +"""A DML column expression. This is a "key" inside of insert().values(), +update().values(), and related. + +These are usually strings or SQL table columns. + +There's also edge cases like JSON expression assignment, which we would want +the DMLColumnRole to be able to accommodate. -_DMLColumnArgument = Union[str, "ColumnClause[Any]", _HasClauseElement] +""" + + +_DMLTableArgument = Union[ + "TableClause", + "Join", + "Alias", + Type[Any], + Inspectable[_HasClauseElement], + _HasClauseElement, +] _PropagateAttrsType = util.immutabledict[str, Any] _TypeEngineArgument = Union[Type["TypeEngine[_T]"], "TypeEngine[_T]"] +if TYPE_CHECKING: -def is_named_from_clause(t: FromClauseRole) -> TypeGuard[NamedFromClause]: - return t.named_with_column + def is_named_from_clause(t: FromClauseRole) -> TypeGuard[NamedFromClause]: + ... + def is_column_element(c: ClauseElement) -> TypeGuard[ColumnElement[Any]]: + ... -def is_column_element(c: ClauseElement) -> TypeGuard[ColumnElement[Any]]: - return c._is_column_element + def is_text_clause(c: ClauseElement) -> TypeGuard[TextClause]: + ... + def is_from_clause(c: ClauseElement) -> TypeGuard[FromClause]: + ... -def is_text_clause(c: ClauseElement) -> TypeGuard[TextClause]: - return c._is_text_clause + def is_tuple_type(t: TypeEngine[Any]) -> TypeGuard[TupleType]: + ... + + def is_table_value_type(t: TypeEngine[Any]) -> TypeGuard[TableValueType]: + ... + + def is_select_base(t: ReturnsRows) -> TypeGuard[SelectBase]: + ... + + def is_select_statement(t: ReturnsRows) -> TypeGuard[Select]: + ... + + def is_table(t: FromClause) -> TypeGuard[TableClause]: + ... + + def is_subquery(t: FromClause) -> TypeGuard[Subquery]: + ... + +else: + is_named_from_clause = operator.attrgetter("named_with_column") + is_column_element = operator.attrgetter("_is_column_element") + is_text_clause = operator.attrgetter("_is_text_clause") + is_from_clause = operator.attrgetter("_is_from_clause") + is_tuple_type = operator.attrgetter("_is_tuple_type") + is_table_value_type = operator.attrgetter("_is_table_value") + is_select_base = operator.attrgetter("_is_select_base") + is_select_statement = operator.attrgetter("_is_select_statement") + is_table = operator.attrgetter("_is_table") + is_subquery = operator.attrgetter("_is_subquery") def has_schema_attr(t: FromClauseRole) -> TypeGuard[TableClause]: @@ -95,9 +204,5 @@ def is_quoted_name(s: str) -> TypeGuard[quoted_name]: return hasattr(s, "quote") -def is_tuple_type(t: TypeEngine[Any]) -> TypeGuard[TupleType]: - return t._is_tuple_type - - def is_has_clause_element(s: object) -> TypeGuard[_HasClauseElement]: return hasattr(s, "__clause_element__") |