summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES10
-rw-r--r--lib/sqlalchemy/schema.py13
-rw-r--r--test/sql/test_constraints.py43
3 files changed, 65 insertions, 1 deletions
diff --git a/CHANGES b/CHANGES
index 5e5790554..8d3153bed 100644
--- 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
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index 0a22d8855..f710ae736 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -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):
diff --git a/test/sql/test_constraints.py b/test/sql/test_constraints.py
index 5ea5a7eda..546a14ca2 100644
--- a/test/sql/test_constraints.py
+++ b/test/sql/test_constraints.py
@@ -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