]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [bug] All of UniqueConstraint, ForeignKeyConstraint,
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 24 Apr 2012 20:08:35 +0000 (16:08 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 24 Apr 2012 20:08:35 +0000 (16:08 -0400)
CheckConstraint, and PrimaryKeyConstraint will
attach themselves to their parent table automatically
when they refer to a Table-bound Column object directly
(i.e. not just string column name), and refer to
one and only one Table.   Prior to 0.8 this behavior
occurred for UniqueConstraint and PrimaryKeyConstraint,
but not ForeignKeyConstraint or CheckConstraint.
[ticket:2410]

CHANGES
lib/sqlalchemy/schema.py
test/sql/test_constraints.py

diff --git a/CHANGES b/CHANGES
index 5e5790554f24d5186011839e50848efacfc8f74a..8d3153bed1872f6455ac10826f3f264eaa107104 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -173,6 +173,16 @@ CHANGES
     by setting "case_insensitive=False" on 
     create_engine().  [ticket:2423]
 
+  - [bug] All of UniqueConstraint, ForeignKeyConstraint,
+    CheckConstraint, and PrimaryKeyConstraint will
+    attach themselves to their parent table automatically
+    when they refer to a Table-bound Column object directly
+    (i.e. not just string column name), and refer to
+    one and only one Table.   Prior to 0.8 this behavior
+    occurred for UniqueConstraint and PrimaryKeyConstraint,
+    but not ForeignKeyConstraint or CheckConstraint.
+    [ticket:2410]
+
   - [bug] column.label(None) now produces an 
     anonymous label, instead of returning the
     column object itself, consistent with the behavior
index 0a22d8855d678afc39a20000c2308afd87dbf07b..f710ae736792d9e43b252f5f2ff5016f5eb0f687 100644 (file)
@@ -1980,6 +1980,14 @@ class CheckConstraint(Constraint):
         self.sqltext = expression._literal_as_text(sqltext)
         if table is not None:
             self._set_parent_with_dispatch(table)
+        else:
+            cols = sqlutil.find_columns(self.sqltext)
+            tables = set([c.table for c in cols 
+                        if c.table is not None])
+            if len(tables) == 1:
+                self._set_parent_with_dispatch(
+                        tables.pop())
+
 
     def __visit_name__(self):
         if isinstance(self.parent, Table):
@@ -2083,6 +2091,11 @@ class ForeignKeyConstraint(Constraint):
 
         if table is not None:
             self._set_parent_with_dispatch(table)
+        elif columns and \
+            isinstance(columns[0], Column) and \
+            columns[0].table is not None:
+            self._set_parent_with_dispatch(columns[0].table)
+
 
     @property
     def columns(self):
index 5ea5a7edaac8ecd5af58f88a476ee950cf536d2f..546a14ca2f9e452ddbce2e58b370b4cd4c06245c 100644 (file)
@@ -437,7 +437,8 @@ class ConstraintCompilationTest(fixtures.TestBase, AssertsCompiledSQL):
         )
 
         constraint = CheckConstraint('a < b',name="my_test_constraint",
-                                        deferrable=True,initially='DEFERRED', table=t)
+                                        deferrable=True,initially='DEFERRED', 
+                                        table=t)
 
 
         # before we create an AddConstraint,
@@ -513,4 +514,44 @@ class ConstraintCompilationTest(fixtures.TestBase, AssertsCompiledSQL):
             "ALTER TABLE tbl ADD PRIMARY KEY (a)"
         )
 
+    def test_auto_append_constraint(self):
+        m = MetaData()
+
+        t = Table('tbl', m,
+                  Column('a', Integer),
+                  Column('b', Integer)
+        )
+
+        t2 = Table('t2', m,
+                Column('a', Integer),
+                Column('b', Integer)
+        )
+
+        for c in (
+            UniqueConstraint(t.c.a),
+            CheckConstraint(t.c.a > 5),
+            ForeignKeyConstraint([t.c.a], [t2.c.a]),
+            PrimaryKeyConstraint(t.c.a)
+        ):
+            assert c in t.constraints
+            t.append_constraint(c)
+            assert c in t.constraints
 
+        c = Index('foo', t.c.a)
+        assert c in t.indexes
+
+    def test_ambig_check_constraint_auto_append(self):
+        m = MetaData()
+
+        t = Table('tbl', m,
+                  Column('a', Integer),
+                  Column('b', Integer)
+        )
+
+        t2 = Table('t2', m,
+                Column('a', Integer),
+                Column('b', Integer)
+        )
+        c = CheckConstraint(t.c.a > t2.c.b)
+        assert c not in t.constraints
+        assert c not in t2.constraints
\ No newline at end of file