1. Marc Abramowitz
  2. sqlalchemy_msabramo_tox

Commits

Mike Bayer  committed d41cd1f

- mapper() will ignore non-configured foreign keys
to unrelated tables when determining inherit
condition between parent and child class.
This is equivalent to behavior already
applied to declarative. [ticket:2153]
Also in 0.6.8.

  • Participants
  • Parent commits 5892f58
  • Branches default

Comments (0)

Files changed (5)

File CHANGES

View file
  • Ignore whitespace
     in the join condition.  [ticket:2149]
     Also in 0.6.8.
 
+  - mapper() will ignore non-configured foreign keys
+    to unrelated tables when determining inherit
+    condition between parent and child class.
+    This is equivalent to behavior already 
+    applied to declarative.  [ticket:2153]
+    Also in 0.6.8.
+
   - It is an error to call query.get() when the
     given entity is not a single, full class 
     entity or mapper (i.e. a column).  This is

File lib/sqlalchemy/ext/declarative.py

View file
  • Ignore whitespace
         inherited_mapper = class_mapper(mapper_args['inherits'],
                                             compile=False)
         inherited_table = inherited_mapper.local_table
-        if 'inherit_condition' not in mapper_args and table is not None:
-            # figure out the inherit condition with relaxed rules
-            # about nonexistent tables, to allow for ForeignKeys to
-            # not-yet-defined tables (since we know for sure that our
-            # parent table is defined within the same MetaData)
-            mapper_args['inherit_condition'] = sql_util.join_condition(
-                mapper_args['inherits'].__table__, table,
-                ignore_nonexistent_tables=True)
 
         if table is None:
             # single table inheritance.

File lib/sqlalchemy/orm/mapper.py

View file
  • Ignore whitespace
                         # want (allows test/inheritance.InheritTest4 to pass)
                         self.inherit_condition = sqlutil.join_condition(
                                                     self.inherits.local_table,
-                                                    self.local_table)
+                                                    self.local_table,
+                                                    ignore_nonexistent_tables=True)
                     self.mapped_table = sql.join(
                                                 self.inherits.mapped_table, 
                                                 self.local_table,

File test/orm/inheritance/test_basic.py

View file
  • Ignore whitespace
         mc = mapper(C, child, inherits=P, primary_key=[parent.c.id])
         eq_(mc.primary_key, (parent.c.id,))
 
+class InhCondTest(fixtures.TestBase):
+    def test_inh_cond_ignores_others(self):
+        metadata = MetaData()
+        base_table = Table("base", metadata,
+            Column("id", Integer, primary_key=True)
+        )
+        derived_table = Table("derived", metadata,
+            Column("id", Integer, ForeignKey("base.id"), primary_key=True),
+            Column("owner_id", Integer, ForeignKey("owner.owner_id"))
+        )
+
+        class Base(object):
+            pass
+
+        class Derived(Base):
+            pass
+
+        mapper(Base, base_table)
+        # succeeds, despite "owner" table not configured yet
+        m2 = mapper(Derived, derived_table, 
+                    inherits=Base)
+        assert m2.inherit_condition.compare(
+                    base_table.c.id==derived_table.c.id
+                )
+
+    def test_inh_cond_fails_notfound(self):
+        metadata = MetaData()
+        base_table = Table("base", metadata,
+            Column("id", Integer, primary_key=True)
+        )
+        derived_table = Table("derived", metadata,
+            Column("id", Integer, primary_key=True),
+        )
+
+        class Base(object):
+            pass
+
+        class Derived(Base):
+            pass
+
+        mapper(Base, base_table)
+        assert_raises_message(
+            sa_exc.ArgumentError,
+            "Can't find any foreign key relationships between "
+            "'base' and 'derived'.",
+            mapper,
+            Derived, derived_table,  inherits=Base
+        )
+
+    def test_inh_cond_fails_separate_metas(self):
+        m1 = MetaData()
+        m2 = MetaData()
+        base_table = Table("base", m1,
+            Column("id", Integer, primary_key=True)
+        )
+        derived_table = Table("derived", m2,
+            Column("id", Integer, ForeignKey('base.id'), 
+                primary_key=True),
+        )
+
+        class Base(object):
+            pass
+
+        class Derived(Base):
+            pass
+
+        mapper(Base, base_table)
+
+        # this used to be "can't resolve foreign key base.id",
+        # but with the flag on, we just get "can't find".  this is
+        # the less-than-ideal case that prevented us from doing this
+        # for mapper(), not just declarative, in the first place.  
+        # there is no case where the failure would be silent - 
+        # there is either a single join condition between the two tables 
+        # or there's not.
+        assert_raises_message(
+            sa_exc.ArgumentError,
+            "Can't find any foreign key relationships between "
+            "'base' and 'derived'.",
+            mapper,
+            Derived, derived_table,  inherits=Base
+        )
+
 class PKDiscriminatorTest(fixtures.MappedTest):
     @classmethod
     def define_tables(cls, metadata):

File test/orm/test_mapper.py

View file
  • Ignore whitespace
             m3.identity_key_from_instance(AddressUser())
         )
 
+
+
     def test_illegal_non_primary(self):
         users, Address, addresses, User = (self.tables.users,
                                 self.classes.Address,