diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-03-26 12:30:35 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-03-28 09:59:51 -0400 |
| commit | 9e85abb221af13057621ea066af4e15b2f1dfb03 (patch) | |
| tree | fdf0ca34554fbd87f9a5538cd28ab877434530cc /test/orm | |
| parent | ce4e1770f01a6c19d3a55621529e3f98607d7824 (diff) | |
| download | sqlalchemy-9e85abb221af13057621ea066af4e15b2f1dfb03.tar.gz | |
disable raise sql for the delete cascade
Towards maintaining consistency with unit-of-work changes made for
:ticket:`5984` and :ticket:`8862`, both of which disable "lazy='raise'"
handling within :class:`_orm.Session` processes that aren't triggered by
attribute access, the :meth:`_orm.Session.delete` method will now also
disable "lazy='raise'" handling when it traverses relationship paths in
order to process the "delete" and "delete-orphan" cascade rules.
Previously, there was no easy way to generically call
:meth:`_orm.Session.delete` on an object that had "lazy='raise'" set up
such that only the necessary relationships would be loaded. As
"lazy='raise'" is primarily intended to catch SQL loading that emits on
attribute access, :meth:`_orm.Session.delete` is now made to behave like
other :class:`_orm.Session` methods including :meth:`_orm.Session.merge` as
well as :meth:`_orm.Session.flush` along with autoflush.
Fixes: #9549
Change-Id: Ie049e66ce2bd35900eae4af0e9b795633303ca63
Diffstat (limited to 'test/orm')
| -rw-r--r-- | test/orm/test_cascade.py | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/test/orm/test_cascade.py b/test/orm/test_cascade.py index a46164703..8a545b03b 100644 --- a/test/orm/test_cascade.py +++ b/test/orm/test_cascade.py @@ -63,10 +63,10 @@ class CascadeArgTest(fixtures.MappedTest): @classmethod def setup_classes(cls): - class User(cls.Basic): + class User(cls.Comparable): pass - class Address(cls.Basic): + class Address(cls.Comparable): pass def test_delete_with_passive_deletes_all(self): @@ -173,6 +173,78 @@ class CascadeArgTest(fixtures.MappedTest): eq_(rel.cascade, {"save-update", "merge", "expunge"}) +class CasadeWithRaiseloadTest(fixtures.MappedTest): + @classmethod + def define_tables(cls, metadata): + Table( + "users", + metadata, + Column( + "id", Integer, primary_key=True, test_needs_autoincrement=True + ), + Column("name", String(30), nullable=False), + ) + Table( + "addresses", + metadata, + Column( + "id", Integer, primary_key=True, test_needs_autoincrement=True + ), + Column("user_id", Integer, ForeignKey("users.id")), + Column("email_address", String(50), nullable=False), + ) + + @classmethod + def setup_classes(cls): + class User(cls.Comparable): + pass + + class Address(cls.Comparable): + pass + + def test_delete_skips_lazy_raise(self): + User, Address = self.classes.User, self.classes.Address + users, addresses = self.tables.users, self.tables.addresses + + self.mapper_registry.map_imperatively( + User, + users, + properties={ + "addresses": relationship( + Address, cascade="all, delete-orphan", lazy="raise" + ) + }, + ) + self.mapper_registry.map_imperatively(Address, addresses) + + self.mapper_registry.metadata.create_all(testing.db) + + sess = fixture_session() + u1 = User( + name="u1", + addresses=[ + Address(email_address="e1"), + Address(email_address="e2"), + ], + ) + sess.add(u1) + sess.commit() + + eq_( + sess.scalars( + select(Address).order_by(Address.email_address) + ).all(), + [Address(email_address="e1"), Address(email_address="e2")], + ) + + sess.close() + + sess.delete(u1) + sess.commit() + + eq_(sess.scalars(select(Address)).all(), []) + + class O2MCascadeDeleteOrphanTest(fixtures.MappedTest): run_inserts = None |
