summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/context.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-07-10 21:24:17 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-07-10 21:27:12 -0400
commit3916bfc9ccf2904f69498075849a82ceee225b3a (patch)
treeab835bf174a4047de0d2b62f6a3ac2731c321434 /lib/sqlalchemy/orm/context.py
parent805a1323b973a30af99ce506dd5c5c4ab96cff0f (diff)
downloadsqlalchemy-3916bfc9ccf2904f69498075849a82ceee225b3a.tar.gz
support "SELECT *" for ORM queries
A :func:`_sql.select` construct that is passed a sole '*' argument for ``SELECT *``, either via string, :func:`_sql.text`, or :func:`_sql.literal_column`, will be interpreted as a Core-level SQL statement rather than as an ORM level statement. This is so that the ``*``, when expanded to match any number of columns, will result in all columns returned in the result. the ORM- level interpretation of :func:`_sql.select` needs to know the names and types of all ORM columns up front which can't be achieved when ``'*'`` is used. If ``'*`` is used amongst other expressions simultaneously with an ORM statement, an error is raised as this can't be interpreted correctly by the ORM. Fixes: #8235 Change-Id: Ic8e84491e14acdc8570704eadeaeaf6e16b1e870
Diffstat (limited to 'lib/sqlalchemy/orm/context.py')
-rw-r--r--lib/sqlalchemy/orm/context.py12
1 files changed, 12 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py
index e743eeed5..20a03e9b4 100644
--- a/lib/sqlalchemy/orm/context.py
+++ b/lib/sqlalchemy/orm/context.py
@@ -219,6 +219,7 @@ class ORMCompileState(CompileState):
("_set_base_alias", InternalTraversal.dp_boolean),
("_for_refresh_state", InternalTraversal.dp_boolean),
("_render_for_subquery", InternalTraversal.dp_boolean),
+ ("_is_star", InternalTraversal.dp_boolean),
]
# set to True by default from Query._statement_20(), to indicate
@@ -241,6 +242,7 @@ class ORMCompileState(CompileState):
_set_base_alias = False
_for_refresh_state = False
_render_for_subquery = False
+ _is_star = False
attributes: Dict[Any, Any]
global_attributes: Dict[Any, Any]
@@ -422,6 +424,8 @@ class ORMCompileState(CompileState):
load_options = execution_options.get(
"_sa_orm_load_options", QueryContext.default_load_options
)
+ if compile_state.compile_options._is_star:
+ return result
querycontext = QueryContext(
compile_state,
@@ -1023,6 +1027,11 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
self._for_update_arg = query._for_update_arg
+ if self.compile_options._is_star and (len(self._entities) != 1):
+ raise sa_exc.CompileError(
+ "Can't generate ORM query that includes multiple expressions "
+ "at the same time as '*'; query for '*' alone if present"
+ )
for entity in self._entities:
entity.setup_compile_state(self)
@@ -2761,6 +2770,9 @@ class _RawColumnEntity(_ColumnEntity):
self.raw_column_index = raw_column_index
self.translate_raw_column = raw_column_index is not None
+ if column._is_star:
+ compile_state.compile_options += {"_is_star": True}
+
if not is_current_entities or column._is_text_clause:
self._label_name = None
else: