]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [bug] A warning is emitted when a not-present
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 21 Feb 2012 15:49:38 +0000 (10:49 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 21 Feb 2012 15:49:38 +0000 (10:49 -0500)
column is stated in the values() clause
of an insert() or update() construct.
Will move to an exception in 0.8.
[ticket:2413]

CHANGES
lib/sqlalchemy/sql/compiler.py
test/sql/test_compiler.py

diff --git a/CHANGES b/CHANGES
index c1869f55564c9056c78bf59abc51c566d2a452b1..d45f616a00a6e0d7e3b51d1965067052658b2b1c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -49,6 +49,12 @@ CHANGES
     so that .key takes precedence, but this
     is not decided on yet.  [ticket:2392]
 
+  - [bug] A warning is emitted when a not-present
+    column is stated in the values() clause
+    of an insert() or update() construct.
+    Will move to an exception in 0.8.
+    [ticket:2413]
+
   - [bug] A significant change to how labeling
     is applied to columns in SELECT statements
     allows "truncated" labels, that is label names
index de18c48f91b4978b78075ed7610c69a69a6ca4d1..1db88c68c90ff9868e9c09d7ffc7e58733a5a09a 100644 (file)
@@ -1145,7 +1145,6 @@ class SQLCompiler(engine.Compiled):
             for k, v in stmt.parameters.iteritems():
                 parameters.setdefault(sql._column_as_key(k), v)
 
-
         # create a list of column assignment clauses as tuples
         values = []
 
@@ -1204,7 +1203,7 @@ class SQLCompiler(engine.Compiled):
         # "defaults", "primary key cols", etc.
         for c in stmt.table.columns:
             if c.key in parameters and c.key not in check_columns:
-                value = parameters[c.key]
+                value = parameters.pop(c.key)
                 if sql._is_literal(value):
                     value = self._create_crud_bind_param(
                                     c, value, required=value is required)
@@ -1300,6 +1299,17 @@ class SQLCompiler(engine.Compiled):
                         self.prefetch.append(c)
                 elif c.server_onupdate is not None:
                     self.postfetch.append(c)
+
+        if parameters and stmt.parameters:
+            check = set(parameters).intersection(
+                sql._column_as_key(k) for k in stmt.parameters
+            )
+            if check:
+                util.warn(
+                    "Unconsumed column names: %s" % 
+                    (", ".join(check))
+                )
+
         return values
 
     def visit_delete(self, delete_stmt):
index 6330ee34e9ae2c7ba86d1684b1b016278cb87618..528a49558363588d840a26eea9ce65ad3d5844b0 100644 (file)
@@ -2855,6 +2855,50 @@ class CRUDTest(fixtures.TestBase, AssertsCompiledSQL):
         self.assert_compile(i, "INSERT INTO foo (x, y) VALUES ((:param_1 + :x2), :y)",
                                     params={'x2':1, 'y':2})
 
+    def test_unconsumed_names(self):
+        t = table("t", column("x"), column("y"))
+        t2 = table("t2", column("q"), column("z"))
+        assert_raises_message(
+            exc.SAWarning,
+            "Unconsumed column names: z",
+            t.insert().values(x=5, z=5).compile,
+        )
+        assert_raises_message(
+            exc.SAWarning,
+            "Unconsumed column names: z",
+            t.update().values(x=5, z=5).compile,
+        )
+
+        assert_raises_message(
+            exc.SAWarning,
+            "Unconsumed column names: j",
+            t.update().values(x=5, j=7).values({t2.c.z:5}).
+                where(t.c.x==t2.c.q).compile,
+        )
+
+        # bindparam names don't get counted
+        i = t.insert().values(x=3 + bindparam('x2'))
+        self.assert_compile(
+            i,
+            "INSERT INTO t (x) VALUES ((:param_1 + :x2))"
+        )
+
+        # even if in the params list
+        i = t.insert().values(x=3 + bindparam('x2'))
+        self.assert_compile(
+            i,
+            "INSERT INTO t (x) VALUES ((:param_1 + :x2))",
+            params={"x2":1}
+        )
+
+        assert_raises_message(
+            exc.SAWarning,
+            "Unconsumed column names: j",
+            t.update().values(x=5, j=7).compile,
+            column_keys=['j']
+        )
+
+
     def test_labels_no_collision(self):
 
         t = table('foo', column('id'), column('foo_id'))