diff options
| -rw-r--r-- | CHANGES | 10 | ||||
| -rw-r--r-- | lib/sqlalchemy/schema.py | 13 | ||||
| -rw-r--r-- | test/sql/test_constraints.py | 43 |
3 files changed, 65 insertions, 1 deletions
@@ -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 |
