diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-11-18 12:46:25 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-11-18 12:46:25 -0500 |
commit | d4c170238dc95eeb2dc7e6c5e03270fbc8b36f8f (patch) | |
tree | b5efb43fdbfb5eaa80b4cc768471313e4e93f8e9 /test | |
parent | 9141b6c15eac4827f0df2e3f87f331c821d13b5a (diff) | |
download | sqlalchemy-d4c170238dc95eeb2dc7e6c5e03270fbc8b36f8f.tar.gz |
disable raiseerr for refresh state loader options
Fixed ORM regression where the new behavior of "eager loaders run on
unexpire" added in :ticket:`1763` would lead to loader option errors being
raised inappropriately for the case where a single :class:`_orm.Query` or
:class:`_sql.Select` were used to load multiple kinds of entities, along
with loader options that apply to just one of those kinds of entity like a
:func:`_orm.joinedload`, and later the objects would be refreshed from
expiration, where the loader options would attempt to be applied to the
mismatched object type and then raise an exception. The check for this
mismatch now bypasses raising an error for this case.
Fixes: #7318
Change-Id: I111e0f3e0fb0447355574cbdcde002f734833490
Diffstat (limited to 'test')
-rw-r--r-- | test/orm/test_expire.py | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/test/orm/test_expire.py b/test/orm/test_expire.py index ae7ac010b..a5abcb355 100644 --- a/test/orm/test_expire.py +++ b/test/orm/test_expire.py @@ -25,6 +25,7 @@ from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures +from sqlalchemy.testing.assertions import expect_raises_message from sqlalchemy.testing.assertsql import CountStatements from sqlalchemy.testing.fixtures import fixture_session from sqlalchemy.testing.schema import Column @@ -850,6 +851,58 @@ class ExpireTest(_fixtures.FixtureTest): assert "name" in u.__dict__ assert len(u.addresses) == 2 + @testing.combinations( + (True, False), + (False, False), + (False, True), + ) + def test_skip_options_that_dont_match(self, test_control_case, do_expire): + """test #7318""" + + User, Address, Order = self.classes("User", "Address", "Order") + users, addresses, orders = self.tables("users", "addresses", "orders") + + self.mapper_registry.map_imperatively(Order, orders) + + self.mapper_registry.map_imperatively( + User, + users, + properties={ + "addresses": relationship( + Address, backref="user", lazy="joined" + ), + "orders": relationship(Order), + }, + ) + self.mapper_registry.map_imperatively(Address, addresses) + sess = fixture_session() + + if test_control_case: + # this would be the error we are skipping, make sure it happens + # for up front + with expect_raises_message( + sa.exc.ArgumentError, + 'Mapped attribute "User.addresses" does not apply to ' + "any of the root entities in this query", + ): + row = sess.execute( + select(Order).options(joinedload(User.addresses)) + ).first() + else: + stmt = ( + select(User, Order) + .join_from(User, Order) + .options(joinedload(User.addresses)) + .order_by(User.id, Order.id) + ) + + row = sess.execute(stmt).first() + + u1, o1 = row + if do_expire: + sess.expire(o1) + eq_(o1.description, "order 1") + def test_mapper_joinedload_props_load(self): users, Address, addresses, User = ( self.tables.users, |