From: Mike Bayer Date: Fri, 28 Aug 2020 21:56:43 +0000 (-0400) Subject: See if the future is here X-Git-Tag: rel_1_4_0b1~142 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e800285508ecd869c6874fed6f46ff68815d184;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git See if the future is here The docs are going to talk a lot about session.execute(select()) for ORM queries, and additionally it's much easier to help users with queries and such if we can use this new syntax. I'm hoping to see how hard it is to get a unified tutorial started that switches to new syntax. Basically, new syntax is much easier to explain and less buggy. But, if we are starting to present new syntax with the explicit goal of being easier to explain for less experienced programmers, the "future" thing is going to just be an impediment to that. See if we can remove "future" from session.execute(), so that ORM-enabled select() statements return ORM results at that level. This does not change the presence of the "future" flag for the Session's construction and for its transactional behaviors. The only perceptible change of the future flag for session.execute() is that session.execute(select()) where the statement has ORM entities in it now returns ORM new style tuples rather than old style tuples. Like mutating a URL, it's hopefully not very common that people are doing this. Change-Id: I0aa10322bb787d554d32772e3bc60548f1bf6206 --- diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index 97c825f02a..1fad892860 100644 --- a/lib/sqlalchemy/ext/baked.py +++ b/lib/sqlalchemy/ext/baked.py @@ -411,7 +411,7 @@ class Result(object): ) result = self.session.execute( - statement, params, execution_options=execution_options, future=True + statement, params, execution_options=execution_options ) if result._attributes.get("is_single_entity", False): result = result.scalars() diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index 7832152a24..41d0fabd23 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -461,7 +461,7 @@ class AppenderQuery(Generative): % (orm_util.instance_str(instance), self.attr.key) ) - result = sess.execute(self._statement, future=True) + result = sess.execute(self._statement) result = result.scalars() if result._attributes.get("filtered", False): diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index fd3e92055b..d397141471 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -498,7 +498,6 @@ def load_on_pk_identity( params=params, execution_options=execution_options, bind_arguments=bind_arguments, - future=True, ) .unique() .scalars() diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index 676dd438c1..49b29a6bc0 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -2021,7 +2021,6 @@ class BulkUDCompileState(CompileState): execution_options, bind_arguments, _add_event=skip_for_full_returning, - future=True, ) matched_rows = result.fetchall() diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 68ca0365b7..37ff489644 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -2726,7 +2726,6 @@ class Query( statement, params, execution_options={"_sa_orm_load_options": self.load_options}, - future=True, ) # legacy: automatically set scalars, unique @@ -3013,7 +3012,6 @@ class Query( delete_, self._params, execution_options={"synchronize_session": synchronize_session}, - future=True, ) bulk_del.result = result self.session.dispatch.after_bulk_delete(bulk_del) @@ -3089,7 +3087,6 @@ class Query( upd, self._params, execution_options={"synchronize_session": synchronize_session}, - future=True, ) bulk_ud.result = result self.session.dispatch.after_bulk_update(bulk_ud) diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index ed1af0a803..dc3af80f24 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -232,7 +232,6 @@ class ORMExecuteState(util.MemoizedSlots): _execution_options, _bind_arguments, _parent_execute_state=self, - future=self._future, ) @property @@ -1431,7 +1430,6 @@ class Session(_SessionClassMethods): params=None, execution_options=util.EMPTY_DICT, bind_arguments=None, - future=False, _parent_execute_state=None, _add_event=None, **kw @@ -1538,14 +1536,6 @@ class Session(_SessionClassMethods): Contents of this dictionary are passed to the :meth:`.Session.get_bind` method. - :param future: - Use future style execution for this statement. This is - the same effect as the :paramref:`_orm.Session.future` flag, - except at the level of this single statement execution. See - that flag for details. - - .. versionadded:: 1.4 - :param mapper: deprecated; use the bind_arguments dictionary @@ -1571,8 +1561,6 @@ class Session(_SessionClassMethods): """ statement = coercions.expect(roles.CoerceTextStatementRole, statement) - future = future or self.future - if not bind_arguments: bind_arguments = kw elif kw: @@ -1605,13 +1593,9 @@ class Session(_SessionClassMethods): ) else: bind_arguments.setdefault("clause", statement) - if future: - # not sure if immutabledict is working w/ this syntax - # execution_options = - # execution_options.union(future_result=True) - execution_options = execution_options.union( - {"future_result": True} - ) + execution_options = execution_options.union( + {"future_result": True} + ) if _parent_execute_state: events_todo = _parent_execute_state._remaining_events() @@ -1637,7 +1621,6 @@ class Session(_SessionClassMethods): if result: return result - # TODO: coverage for this pattern statement = orm_exec_state.statement execution_options = orm_exec_state.local_execution_options diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 53166bd918..b9826ac87d 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -989,7 +989,7 @@ class LazyLoader(AbstractRelationshipLoader, util.MemoizedSlots): ) result = session.execute( - stmt, params, future=True, execution_options=execution_options + stmt, params, execution_options=execution_options ) result = result.unique().scalars().all() @@ -2794,7 +2794,6 @@ class SelectInLoader(PostLoader, util.MemoizedSlots): for key in chunk ] }, - future=True, ).unique() } @@ -2839,7 +2838,7 @@ class SelectInLoader(PostLoader, util.MemoizedSlots): data = collections.defaultdict(list) for k, v in itertools.groupby( context.session.execute( - q, params={"primary_keys": primary_keys}, future=True + q, params={"primary_keys": primary_keys} ).unique(), lambda x: x[0], ): diff --git a/test/ext/test_baked.py b/test/ext/test_baked.py index c8e83bbd74..49529f81ca 100644 --- a/test/ext/test_baked.py +++ b/test/ext/test_baked.py @@ -1067,15 +1067,13 @@ class CustomIntegrationTest(testing.AssertsCompiledSQL, BakedTest): q = sess.query(User).filter(User.id == 7).set_cache_key("user7") eq_( - sess.execute(q, future=True).all(), - [(User(id=7, addresses=[Address(id=1)]),)], + sess.execute(q).all(), [(User(id=7, addresses=[Address(id=1)]),)], ) eq_(list(q.cache), ["user7"]) eq_( - sess.execute(q, future=True).all(), - [(User(id=7, addresses=[Address(id=1)]),)], + sess.execute(q).all(), [(User(id=7, addresses=[Address(id=1)]),)], ) def test_use_w_baked(self): diff --git a/test/orm/test_query.py b/test/orm/test_query.py index e43504d9e2..a0171295b2 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -188,7 +188,7 @@ class RowTupleTest(QueryTest): mapper(User, users) - s = Session(testing.db, future=True) + s = Session(testing.db) q = testing.resolve_lambda(test_case, **locals()) @@ -212,15 +212,8 @@ class RowTupleTest(QueryTest): row = s.execute(q.order_by(User.id)).first() - # old style row - assert "jack" not in row - assert "jack" in tuple(row) - - row = s.execute(q.order_by(User.id), future=True).first() - - # new style row - not sure what to do here w/ future yet + # s.execute() is now new style row assert "jack" in row - assert "jack" in tuple(row) def test_entity_mapping_access(self): User, users = self.classes.User, self.tables.users @@ -877,7 +870,7 @@ class GetTest(QueryTest): def test_populate_existing_future(self): User, Address = self.classes.User, self.classes.Address - s = Session(testing.db, future=True, autoflush=False) + s = Session(testing.db, autoflush=False) userlist = s.query(User).all() @@ -926,7 +919,7 @@ class GetTest(QueryTest): stmt = select(User).execution_options( populate_existing=True, autoflush=False, yield_per=10 ) - s = Session(testing.db, future=True) + s = Session(testing.db) m1 = mock.Mock() @@ -4630,7 +4623,7 @@ class TextTest(QueryTest, AssertsCompiledSQL): def test_select_star_future(self): User = self.classes.User - sess = Session(testing.db, future=True) + sess = Session(testing.db) eq_( sess.execute( select(User).from_statement( @@ -4678,7 +4671,7 @@ class TextTest(QueryTest, AssertsCompiledSQL): # ordering doesn't matter User = self.classes.User - s = create_session(testing.db, future=True) + s = create_session(testing.db) q = select(User).from_statement( text( "select name, 27 as foo, id as users_id from users order by id" @@ -4725,7 +4718,7 @@ class TextTest(QueryTest, AssertsCompiledSQL): User = self.classes.User Address = self.classes.Address - s = create_session(testing.db, future=True) + s = create_session(testing.db) q = select(User, Address).from_statement( text( "select users.name AS users_name, users.id AS users_id, " @@ -4776,7 +4769,7 @@ class TextTest(QueryTest, AssertsCompiledSQL): User = self.classes.User Address = self.classes.Address - s = create_session(testing.db, future=True) + s = create_session(testing.db) q = ( select(User) .from_statement( @@ -4828,7 +4821,7 @@ class TextTest(QueryTest, AssertsCompiledSQL): User = self.classes.User Address = self.classes.Address - s = create_session(testing.db, future=True) + s = create_session(testing.db) q = ( select(User) .from_statement( @@ -4935,7 +4928,7 @@ class TextTest(QueryTest, AssertsCompiledSQL): def test_whereclause_future(self): User = self.classes.User - s = create_session(testing.db, future=True) + s = create_session(testing.db) eq_( s.execute(select(User).filter(text("id in (8, 9)"))) .scalars()