]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
call iter() on detached/transient dynamic session
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 2 Jul 2024 17:57:47 +0000 (13:57 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 2 Jul 2024 19:03:22 +0000 (15:03 -0400)
Fixed regression going back to 1.4 where accessing a collection using the
"dynamic" strategy on a transient object and attempting to query would
raise an internal error rather than the expected :class:`.NoResultFound`
that occurred in 1.3.

Fixes: #11562
Change-Id: I650305963a17592413520d8d1049c601761a0acc
(cherry picked from commit 4208993938302e34a67e57af710be7d98ff37659)
(cherry picked from commit 1ad8edb9e168bf2f7de88114f7bb6e25c8155b69)

doc/build/changelog/unreleased_14/11562.rst [new file with mode: 0644]
lib/sqlalchemy/orm/dynamic.py
setup.cfg
test/orm/test_dynamic.py

diff --git a/doc/build/changelog/unreleased_14/11562.rst b/doc/build/changelog/unreleased_14/11562.rst
new file mode 100644 (file)
index 0000000..15ccd0d
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, orm, regression
+    :tickets: 11562
+
+    Fixed regression going back to 1.4 where accessing a collection using the
+    "dynamic" strategy on a transient object and attempting to query would
+    raise an internal error rather than the expected :class:`.NoResultFound`
+    that occurred in 1.3.
index 5d5ce3642cb8a50095484ecea47de60ab52a2448..0a0d17c08d843053ffeaf7547daca0413bc97bbb 100644 (file)
@@ -344,10 +344,12 @@ class AppenderMixin(object):
 
             return result.IteratorResult(
                 result.SimpleResultMetaData([self.attr.class_.__name__]),
-                self.attr._get_collection_history(
-                    attributes.instance_state(self.instance),
-                    attributes.PASSIVE_NO_INITIALIZE,
-                ).added_items,
+                iter(
+                    self.attr._get_collection_history(
+                        attributes.instance_state(self.instance),
+                        attributes.PASSIVE_NO_INITIALIZE,
+                    ).added_items
+                ),
                 _source_supports_scalars=True,
             ).scalars()
         else:
index e4cee11058d4eecc8a9da515203f5de793ddbc9f..3f8003a1ed3b7f8f691571b9dda42103a471bd95 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -142,7 +142,7 @@ ignore =
     N801,N802,N806,
     RST304,RST303,RST299,RST399,
     W503,W504
-    U100
+    U100,U101
     IS001
 exclude = .venv,.git,.tox,dist,doc,*egg,build
 import-order-style = google
index 0cb4d76d9c2724b1e2a614dc3bd2fd54ad9dfe50..3997aa9710c5e6c7023f55d80a7f50290b89a365 100644 (file)
@@ -238,6 +238,31 @@ class DynamicTest(_DynamicFixture, _fixtures.FixtureTest, AssertsCompiledSQL):
             use_default_dialect=True,
         )
 
+    @testing.combinations(
+        ("all", []),
+        ("one", exc.NoResultFound),
+        ("one_or_none", None),
+        argnames="method, expected",
+    )
+    @testing.variation("add_to_session", [True, False])
+    def test_transient_raise(self, method, expected, add_to_session):
+        """test 11562"""
+        User, Address = self._user_address_fixture()
+
+        u1 = User(name="u1")
+        if add_to_session:
+            sess = fixture_session()
+            sess.add(u1)
+
+        meth = getattr(u1.addresses, method)
+        if expected is exc.NoResultFound:
+            with expect_raises_message(
+                exc.NoResultFound, "No row was found when one was required"
+            ):
+                meth()
+        else:
+            eq_(meth(), expected)
+
     def test_detached_raise(self):
         """so filtering on a detached dynamic list raises an error..."""