summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/context.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-07-08 14:31:17 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-07-11 14:55:51 -0400
commit5de0f1cf50cc0170d8ea61304e7b887259ab577b (patch)
treed351743b4ce2009584ef494ab33a6c3f81ab6bb4 /lib/sqlalchemy/orm/context.py
parente2d4b2e72cb97bc5612fa9d1ec7d0ab15d38efe1 (diff)
downloadsqlalchemy-5de0f1cf50cc0170d8ea61304e7b887259ab577b.tar.gz
Convert remaining ORM APIs to support 2.0 style
This is kind of a mixed bag of all kinds to help get us to 1.4 betas. The documentation stuff is a work in progress. Lots of other relatively small changes to APIs and things. More commits will follow to continue improving the documentation and transitioning to the 1.4/2.0 hybrid documentation. In particular some refinements to Session usage models so that it can match Engine's scoping / transactional patterns, and a decision to start moving away from "subtransactions" completely. * add select().from_statement() to produce FromStatement in an ORM context * begin referring to select() that has "plugins" for the few edge cases where select() will have ORM-only behaviors * convert dynamic.AppenderQuery to its own object that can use select(), though at the moment it uses Query to support legacy join calling forms. * custom query classes for AppenderQuery are replaced by do_orm_execute() hooks for custom actions, a separate gerrit will document this * add Session.get() to replace query.get() * Deprecate session.begin->subtransaction. propose within the test suite a hypothetical recipe for apps that rely on this pattern * introduce Session construction level context manager, sessionmaker context manager, rewrite the whole top of the session_transaction.rst documentation. Establish context manager patterns for Session that are identical to engine * ensure same begin_nested() / commit() behavior as engine * devise all new "join into an external transaction" recipe, add test support for it, add rules into Session so it just works, write new docs. need to ensure this doesn't break anything * vastly reduce the verbosity of lots of session docs as I dont think people read this stuff and it's difficult to keep current in any case * constructs like case(), with_only_columns() really need to move to *columns, add a coercion rule to just change these. * docs need changes everywhere I look. in_() is not in the Core tutorial? how do people even know about it? Remove tons of cruft from Select docs, etc. * build a system for common ORM options like populate_existing and autoflush to populate from execution options. * others? Change-Id: Ia4bea0f804250e54d90b3884cf8aab8b66b82ecf
Diffstat (limited to 'lib/sqlalchemy/orm/context.py')
-rw-r--r--lib/sqlalchemy/orm/context.py59
1 files changed, 43 insertions, 16 deletions
diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py
index d5f001db1..55a6b4cd2 100644
--- a/lib/sqlalchemy/orm/context.py
+++ b/lib/sqlalchemy/orm/context.py
@@ -188,7 +188,7 @@ class ORMCompileState(CompileState):
raise NotImplementedError()
@classmethod
- def get_column_descriptions(self, statement):
+ def get_column_descriptions(cls, statement):
return _column_descriptions(statement)
@classmethod
@@ -204,8 +204,14 @@ class ORMCompileState(CompileState):
if is_reentrant_invoke:
return statement, execution_options
- load_options = execution_options.get(
- "_sa_orm_load_options", QueryContext.default_load_options
+ (
+ load_options,
+ execution_options,
+ ) = QueryContext.default_load_options.from_execution_options(
+ "_sa_orm_load_options",
+ {"populate_existing", "autoflush", "yield_per"},
+ execution_options,
+ statement._execution_options,
)
bind_arguments["clause"] = statement
@@ -246,6 +252,7 @@ class ORMCompileState(CompileState):
load_options = execution_options.get(
"_sa_orm_load_options", QueryContext.default_load_options
)
+
querycontext = QueryContext(
compile_state,
statement,
@@ -304,7 +311,7 @@ class ORMFromStatementCompileState(ORMCompileState):
self._primary_entity = None
self.use_legacy_query_style = (
- statement_container.compile_options._use_legacy_query_style
+ statement_container._compile_options._use_legacy_query_style
)
self.statement_container = self.select_statement = statement_container
self.requested_statement = statement = statement_container.element
@@ -315,9 +322,9 @@ class ORMFromStatementCompileState(ORMCompileState):
_QueryEntity.to_compile_state(self, statement_container._raw_columns)
- self.compile_options = statement_container.compile_options
+ self.compile_options = statement_container._compile_options
- self.current_path = statement_container.compile_options._current_path
+ self.current_path = statement_container._compile_options._current_path
if toplevel and statement_container._with_options:
self.attributes = {"_unbound_load_dedupes": set()}
@@ -416,8 +423,8 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
# if we are a select() that was never a legacy Query, we won't
# have ORM level compile options.
- statement.compile_options = cls.default_compile_options.safe_merge(
- statement.compile_options
+ statement._compile_options = cls.default_compile_options.safe_merge(
+ statement._compile_options
)
self = cls.__new__(cls)
@@ -434,20 +441,20 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
# indicates this select() came from Query.statement
self.for_statement = (
for_statement
- ) = select_statement.compile_options._for_statement
+ ) = select_statement._compile_options._for_statement
if not for_statement and not toplevel:
# for subqueries, turn off eagerloads.
# if "for_statement" mode is set, Query.subquery()
# would have set this flag to False already if that's what's
# desired
- select_statement.compile_options += {
+ select_statement._compile_options += {
"_enable_eagerloads": False,
}
# generally if we are from Query or directly from a select()
self.use_legacy_query_style = (
- select_statement.compile_options._use_legacy_query_style
+ select_statement._compile_options._use_legacy_query_style
)
self._entities = []
@@ -457,15 +464,15 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
self._no_yield_pers = set()
# legacy: only for query.with_polymorphic()
- if select_statement.compile_options._with_polymorphic_adapt_map:
+ if select_statement._compile_options._with_polymorphic_adapt_map:
self._with_polymorphic_adapt_map = dict(
- select_statement.compile_options._with_polymorphic_adapt_map
+ select_statement._compile_options._with_polymorphic_adapt_map
)
self._setup_with_polymorphics()
_QueryEntity.to_compile_state(self, select_statement._raw_columns)
- self.compile_options = select_statement.compile_options
+ self.compile_options = select_statement._compile_options
# determine label style. we can make different decisions here.
# at the moment, trying to see if we can always use DISAMBIGUATE_ONLY
@@ -479,7 +486,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
else:
self.label_style = self.select_statement._label_style
- self.current_path = select_statement.compile_options._current_path
+ self.current_path = select_statement._compile_options._current_path
self.eager_order_by = ()
@@ -668,7 +675,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
self._polymorphic_adapters = {}
compile_options = cls.default_compile_options.safe_merge(
- query.compile_options
+ query._compile_options
)
# legacy: only for query.with_polymorphic()
if compile_options._with_polymorphic_adapt_map:
@@ -711,6 +718,26 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
for elem in _select_iterables([element]):
yield elem
+ @classmethod
+ @util.preload_module("sqlalchemy.orm.query")
+ def from_statement(cls, statement, from_statement):
+ query = util.preloaded.orm_query
+
+ from_statement = coercions.expect(
+ roles.SelectStatementRole,
+ from_statement,
+ apply_propagate_attrs=statement,
+ )
+
+ stmt = query.FromStatement(statement._raw_columns, from_statement)
+ stmt.__dict__.update(
+ _with_options=statement._with_options,
+ _with_context_options=statement._with_context_options,
+ _execution_options=statement._execution_options,
+ _propagate_attrs=statement._propagate_attrs,
+ )
+ return stmt
+
def _setup_with_polymorphics(self):
# legacy: only for query.with_polymorphic()
for ext_info, wp in self._with_polymorphic_adapt_map.items():