]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed regression from 0.6 whereby if
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 10 Jan 2012 16:43:47 +0000 (11:43 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 10 Jan 2012 16:43:47 +0000 (11:43 -0500)
"load_on_pending" relationship() flag were used
where a non-"get()" lazy clause needed to be
emitted on a pending object, it would fail
to load.

CHANGES
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/expression.py
lib/sqlalchemy/sql/util.py
test/orm/test_load_on_fks.py

diff --git a/CHANGES b/CHANGES
index 2457c966893acfc97e280c3aeb4f8da5741a33e0..fc72a7109c526f4b377e0e321429f0a49a796138 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -23,6 +23,12 @@ CHANGES
     criteria which will join via AND, i.e.
     query.filter(x==y, z>q, ...)
 
+  - Fixed regression from 0.6 whereby if 
+    "load_on_pending" relationship() flag were used
+    where a non-"get()" lazy clause needed to be 
+    emitted on a pending object, it would fail 
+    to load.
+
 - engine
   - [bug] Added __reduce__ to StatementError, 
     DBAPIError so that exceptions are pickleable,
index aa744e0c1f66092adc8156d92e2080e91d682290..724e7dc2a03da550f7bcf511763c4331d537cd77 100644 (file)
@@ -305,18 +305,13 @@ class SQLCompiler(engine.Compiled):
                         raise exc.InvalidRequestError(
                                 "A value is required for bind parameter %r" 
                                 % bindparam.key)
-                elif bindparam.callable:
-                    pd[name] = bindparam.callable()
                 else:
-                    pd[name] = bindparam.value
+                    pd[name] = bindparam.effective_value
             return pd
         else:
             pd = {}
             for bindparam in self.bind_names:
-                if bindparam.callable:
-                    pd[self.bind_names[bindparam]] = bindparam.callable()
-                else:
-                    pd[self.bind_names[bindparam]] = bindparam.value
+                pd[self.bind_names[bindparam]] = bindparam.effective_value
             return pd
 
     params = property(construct_params, doc="""
index 15d2970c20ff1f8172cd06c7f12c18dd825e3d09..9f2a1619508ec65b05c3f6b03a1ca5d0000cb1c4 100644 (file)
@@ -2606,6 +2606,21 @@ class _BindParamClause(ColumnElement):
         else:
             self.type = type_
 
+    @property
+    def effective_value(self):
+        """Return the value of this bound parameter, 
+        taking into account if the ``callable`` parameter
+        was set.  
+        
+        The ``callable`` value will be evaluated
+        and returned if present, else ``value``.
+        
+        """
+        if self.callable:
+            return self.callable()
+        else:
+            return self.value
+
     def _clone(self):
         c = ClauseElement._clone(self)
         if self.unique:
index 33be99d87495967ae88289e52a75a3295f8385dd..97975441e48e2414f204d4659b04b52b6656076c 100644 (file)
@@ -152,13 +152,7 @@ def bind_values(clause):
 
     v = []
     def visit_bindparam(bind):
-        value = bind.value
-
-        # evaluate callables
-        if callable(value):
-            value = value()
-
-        v.append(value)
+        v.append(bind.effective_value)
 
     visitors.traverse(clause, {}, {'bindparam':visit_bindparam})
     return v
index 697be27ff57242ac8c7e3df115ffc24d5c84ba64..031ac66054d0313f2b0bcb4c837d027d39b07ef8 100644 (file)
@@ -151,6 +151,25 @@ class LoadOnFKsTest(AssertsExecutionResults, fixtures.TestBase):
         # ...unless the flag is on
         assert c3.parent is p1
 
+    def test_collection_load_from_pending_populated(self):
+        Parent.children.property.load_on_pending = True
+        p2 = Parent(id=p1.id)
+        sess.add(p2)
+        # load should emit since PK is populated
+        def go():
+            assert p2.children
+        self.assert_sql_count(testing.db, go, 1)
+
+    def test_collection_load_from_pending_no_sql(self):
+        Parent.children.property.load_on_pending = True
+        p2 = Parent(id=None)
+        sess.add(p2)
+        # load should not emit since "None" is the bound
+        # param list
+        def go():
+            assert not p2.children
+        self.assert_sql_count(testing.db, go, 0)
+
     def test_load_on_pending_with_set(self):
         Child.parent.property.load_on_pending = True