detect FK constraint genn'ed against mulitple tables

Issue #2455 resolved
Mike Bayer repo owner created an issue

that is

# raise error
ForeignKeyConstraint(['b']('a',), ['tableb.b']('tablea.a',))

we can't raise this immediately though as the FKC doesn't evaluate until much later.

diff -r 53b4337de3ab4d4abe17ca47903aaaa8664cd50f lib/sqlalchemy/schema.py
--- a/lib/sqlalchemy/schema.py  Tue Apr 03 10:34:48 2012 -0400
+++ b/lib/sqlalchemy/schema.py  Tue Apr 03 12:55:02 2012 -0400
@@ -1386,6 +1386,17 @@
             table = Table(tname, parenttable.metadata,
                           mustexist=True, schema=schema)

+            if not hasattr(self.constraint, '_referred_table'):
+                self.constraint._referred_table = table
+            elif self.constraint._referred_table is not table:
+                raise exc.InvalidRequestError(
+                    'ForeignKeyConstraint on "%s" refers to '
+                    'multiple remote tables: %s and %s' % (
+                    self.constraint._col_description,
+                    self.constraint._referred_table,
+                    table
+                ))
+
             _column = None
             if colname is None:
                 # colname is None in the case that ForeignKey argument
@@ -1849,7 +1860,7 @@

           _create_rule is used by some types to create constraints.
           Currently, its call signature is subject to change at any time.
-        
+
         :param \**kwargs: 
           Dialect-specific keyword parameters, see the documentation
           for various dialects and constraints regarding options here.
@@ -2085,6 +2096,10 @@
             self._set_parent_with_dispatch(table)

     @property
+    def _col_description(self):
+        return ", ".join(self._elements)
+
+    @property
     def columns(self):
         return self._elements.keys()

@@ -2094,6 +2109,7 @@

     def _set_parent(self, table):
         super(ForeignKeyConstraint, self)._set_parent(table)
+
         for col, fk in self._elements.iteritems():
             # string-specified column names now get
             # resolved to Column objects



#!python
from sqlalchemy import *
from sqlalchemy.schema import CreateIndex
from sqlalchemy import DDL

m = MetaData()
t1 = Table('t1', m, Column('x', Integer), Column('y', Integer), 
    ForeignKeyConstraint(['y']('x',), ['t3.y']('t2.x',))
)
t2 = Table('t2', m, Column('x', Integer))
t3 = Table('t3', m, Column('y', Integer))


print t1.join(t2)

Comments (3)

  1. Log in to comment