summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-06-20 18:47:28 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-06-20 18:47:28 -0400
commita1bbf3a005677c1371b02c54343f5407747e336d (patch)
treef3df6031a7ad52e74c1c64b969d0c2a71ea85442
parentd7f467fcd531ff4b2f7fbe07fa24a2b88556c855 (diff)
downloadsqlalchemy-a1bbf3a005677c1371b02c54343f5407747e336d.tar.gz
- Additional checks have been added for the case where an inheriting
mapper is implicitly combining one of its column-based attributes with that of the parent, where those columns normally don't necessarily share the same value. This is an extension of an existing check that was added via :ticket:`1892`; however this new check emits only a warning, instead of an exception, to allow for applications that may be relying upon the existing behavior. fixes #3042
-rw-r--r--doc/build/changelog/changelog_09.rst17
-rw-r--r--doc/build/faq.rst74
-rw-r--r--lib/sqlalchemy/orm/mapper.py23
-rw-r--r--test/ext/declarative/test_inheritance.py2
-rw-r--r--test/orm/inheritance/test_basic.py102
-rw-r--r--test/orm/inheritance/test_manytomany.py4
-rw-r--r--test/orm/test_cycles.py4
-rw-r--r--test/orm/test_events.py18
-rw-r--r--test/orm/test_inspect.py4
-rw-r--r--test/orm/test_mapper.py16
-rw-r--r--test/orm/test_relationships.py8
-rw-r--r--test/orm/test_unitofwork.py22
12 files changed, 218 insertions, 76 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst
index d7abc1798..e3ddc1d1b 100644
--- a/doc/build/changelog/changelog_09.rst
+++ b/doc/build/changelog/changelog_09.rst
@@ -15,6 +15,23 @@
:version: 0.9.5
.. change::
+ :tags: bug, orm
+ :tickets: 3042
+ :versions: 1.0.0
+
+ Additional checks have been added for the case where an inheriting
+ mapper is implicitly combining one of its column-based attributes
+ with that of the parent, where those columns normally don't necessarily
+ share the same value. This is an extension of an existing check that
+ was added via :ticket:`1892`; however this new check emits only a
+ warning, instead of an exception, to allow for applications that may
+ be relying upon the existing behavior.
+
+ .. seealso::
+
+ :ref:`faq_combining_columns`
+
+ .. change::
:tags: bug, sql
:tickets: 3023
:versions: 1.0.0
diff --git a/doc/build/faq.rst b/doc/build/faq.rst
index 8862cac95..0c8314cb5 100644
--- a/doc/build/faq.rst
+++ b/doc/build/faq.rst
@@ -505,6 +505,80 @@ From there, all information about the class can be acquired using such methods a
this differs from :attr:`.Mapper.mapped_table` in the case of a mapper mapped
using inheritance to a composed selectable.
+.. _faq_combining_columns:
+
+I'm getting a warning or error about "Implicitly combining column X under attribute Y"
+--------------------------------------------------------------------------------------
+
+This condition refers to when a mapping contains two columns that are being
+mapped under the same attribute name due to their name, but there's no indication
+that this is intentional. A mapped class needs to have explicit names for
+every attribute that is to store an independent value; when two columns have the
+same name and aren't disambiguated, they fall under the same attribute and
+the effect is that the value from one column is **copied** into the other, based
+on which column was assigned to the attribute first.
+
+This behavior is often desirable and is allowed without warning in the case
+where the two columns are linked together via a foreign key relationship
+within an inheritance mapping. When the warning or exception occurs, the
+issue can be resolved by either assigning the columns to differently-named
+attributes, or if combining them together is desired, by using
+:func:`.column_property` to make this explicit.
+
+Given the example as follows::
+
+ from sqlalchemy import Integer, Column, ForeignKey
+ from sqlalchemy.ext.declarative import declarative_base
+
+ Base = declarative_base()
+
+ class A(Base):
+ __tablename__ = 'a'
+
+ id = Column(Integer, primary_key=True)
+
+ class B(A):
+ __tablename__ = 'b'
+
+ id = Column(Integer, primary_key=True)
+ a_id = Column(Integer, ForeignKey('a.id'))
+
+As of SQLAlchemy version 0.9.5, the above condition is detected, and will
+warn that the ``id`` column of ``A`` and ``B`` is being combined under
+the same-named attribute ``id``, which above is a serious issue since it means
+that a ``B`` object's primary key will always mirror that of its ``A``.
+
+A mapping which resolves this is as follows::
+
+ class A(Base):
+ __tablename__ = 'a'
+
+ id = Column(Integer, primary_key=True)
+
+ class B(A):
+ __tablename__ = 'b'
+
+ b_id = Column('id', Integer, primary_key=True)
+ a_id = Column(Integer, ForeignKey('a.id'))
+
+Suppose we did want ``A.id`` and ``B.id`` to be mirrors of each other, despite
+the fact that ``B.a_id`` is where ``A.id`` is related. We could combine
+them together using :func:`.column_property`::
+
+ class A(Base):
+ __tablename__ = 'a'
+
+ id = Column(Integer, primary_key=True)
+
+ class B(A):
+ __tablename__ = 'b'
+
+ # probably not what you want, but this is a demonstration
+ id = column_property(Column(Integer, primary_key=True), A.id)
+ a_id = Column(Integer, ForeignKey('a.id'))
+
+
+
I'm using Declarative and setting primaryjoin/secondaryjoin using an ``and_()`` or ``or_()``, and I am getting an error message about foreign keys.
------------------------------------------------------------------------------------------------------------------------------------------------------------------
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 373e18271..bac54cc0a 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -1605,13 +1605,22 @@ class Mapper(_InspectionAttr):
prop = self._props.get(key, None)
if isinstance(prop, properties.ColumnProperty):
- if prop.parent is self:
- raise sa_exc.InvalidRequestError(
- "Implicitly combining column %s with column "
- "%s under attribute '%s'. Please configure one "
- "or more attributes for these same-named columns "
- "explicitly."
- % (prop.columns[-1], column, key))
+ if (
+ not self._inherits_equated_pairs or
+ (prop.columns[0], column) not in self._inherits_equated_pairs
+ ) and \
+ not prop.columns[0].shares_lineage(column) and \
+ prop.columns[0] is not self.version_id_col and \
+ column is not self.version_id_col:
+ warn_only = prop.parent is not self
+ msg = ("Implicitly combining column %s with column "
+ "%s under attribute '%s'. Please configure one "
+ "or more attributes for these same-named columns "
+ "explicitly." % (prop.columns[-1], column, key))
+ if warn_only:
+ util.warn(msg)
+ else:
+ raise sa_exc.InvalidRequestError(msg)
# existing properties.ColumnProperty from an inheriting
# mapper. make a copy and append our column to it
diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py
index 57ab027e1..edff4421e 100644
--- a/test/ext/declarative/test_inheritance.py
+++ b/test/ext/declarative/test_inheritance.py
@@ -76,7 +76,7 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
class Bar(Foo):
__tablename__ = 'bar'
- id = Column('id', Integer, primary_key=True)
+ bar_id = Column('id', Integer, primary_key=True)
foo_id = Column('foo_id', Integer)
__mapper_args__ = {'inherit_condition': foo_id == Foo.id}
diff --git a/test/orm/inheritance/test_basic.py b/test/orm/inheritance/test_basic.py
index c3128d264..bac5ad57c 100644
--- a/test/orm/inheritance/test_basic.py
+++ b/test/orm/inheritance/test_basic.py
@@ -28,12 +28,12 @@ class O2MTest(fixtures.MappedTest):
bar = Table('bar', metadata,
Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
- Column('data', String(20)))
+ Column('bar_data', String(20)))
blub = Table('blub', metadata,
Column('id', Integer, ForeignKey('bar.id'), primary_key=True),
Column('foo_id', Integer, ForeignKey('foo.id'), nullable=False),
- Column('data', String(20)))
+ Column('blub_data', String(20)))
def test_basic(self):
class Foo(object):
@@ -184,7 +184,7 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
Column('x', String(10)),
Column('q', String(10)))
t2 = Table('t2', metadata,
- Column('id', Integer, primary_key=True,
+ Column('t2id', Integer, primary_key=True,
test_needs_autoincrement=True),
Column('y', String(10)),
Column('xid', ForeignKey('t1.id')))
@@ -583,7 +583,8 @@ class PolymorphicAttributeManagementTest(fixtures.MappedTest):
polymorphic_identity='a')
mapper(B, table_b, inherits=A,
polymorphic_on=table_b.c.class_name,
- polymorphic_identity='b')
+ polymorphic_identity='b',
+ properties=dict(class_name=[table_a.c.class_name, table_b.c.class_name]))
mapper(C, table_c, inherits=B,
polymorphic_identity='c')
mapper(D, inherits=B,
@@ -854,13 +855,13 @@ class GetTest(fixtures.MappedTest):
bar = Table('bar', metadata,
Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
- Column('data', String(20)))
+ Column('bar_data', String(20)))
blub = Table('blub', metadata,
- Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
+ Column('blub_id', Integer, primary_key=True, test_needs_autoincrement=True),
Column('foo_id', Integer, ForeignKey('foo.id')),
Column('bar_id', Integer, ForeignKey('bar.id')),
- Column('data', String(20)))
+ Column('blub_data', String(20)))
@classmethod
def setup_classes(cls):
@@ -957,7 +958,7 @@ class EagerLazyTest(fixtures.MappedTest):
Column('data', String(30)))
bar = Table('bar', metadata,
Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
- Column('data', String(30)))
+ Column('bar_data', String(30)))
bar_foo = Table('bar_foo', metadata,
Column('bar_id', Integer, ForeignKey('bar.id')),
@@ -1175,9 +1176,11 @@ class JoinedNoFKSortingTest(fixtures.MappedTest):
A, B, C = cls.classes.A, cls.classes.B, cls.classes.C
mapper(A, cls.tables.a)
mapper(B, cls.tables.b, inherits=A,
- inherit_condition=cls.tables.a.c.id == cls.tables.b.c.id)
+ inherit_condition=cls.tables.a.c.id == cls.tables.b.c.id,
+ inherit_foreign_keys=cls.tables.b.c.id)
mapper(C, cls.tables.c, inherits=A,
- inherit_condition=cls.tables.a.c.id == cls.tables.c.c.id)
+ inherit_condition=cls.tables.a.c.id == cls.tables.c.c.id,
+ inherit_foreign_keys=cls.tables.c.c.id)
def test_ordering(self):
B, C = self.classes.B, self.classes.C
@@ -1345,7 +1348,7 @@ class DistinctPKTest(fixtures.MappedTest):
)
employee_table = Table("employees", metadata,
- Column("id", Integer, primary_key=True, test_needs_autoincrement=True),
+ Column("eid", Integer, primary_key=True, test_needs_autoincrement=True),
Column("salary", Integer),
Column("person_id", Integer, ForeignKey("persons.id")),
)
@@ -1375,18 +1378,19 @@ class DistinctPKTest(fixtures.MappedTest):
person_mapper = mapper(Person, person_table)
mapper(Employee, employee_table, inherits=person_mapper,
properties={'pid':person_table.c.id,
- 'eid':employee_table.c.id})
+ 'eid':employee_table.c.eid})
self._do_test(False)
def test_explicit_composite_pk(self):
person_mapper = mapper(Person, person_table)
mapper(Employee, employee_table,
inherits=person_mapper,
- primary_key=[person_table.c.id, employee_table.c.id])
+ properties=dict(id=[employee_table.c.eid, person_table.c.id]),
+ primary_key=[person_table.c.id, employee_table.c.eid])
assert_raises_message(sa_exc.SAWarning,
r"On mapper Mapper\|Employee\|employees, "
"primary key column 'persons.id' is being "
- "combined with distinct primary key column 'employees.id' "
+ "combined with distinct primary key column 'employees.eid' "
"in attribute 'id'. Use explicit properties to give "
"each column its own mapped attribute name.",
self._do_test, True
@@ -1487,7 +1491,7 @@ class OverrideColKeyTest(fixtures.MappedTest):
@classmethod
def define_tables(cls, metadata):
- global base, subtable
+ global base, subtable, subtable_two
base = Table('base', metadata,
Column('base_id', Integer, primary_key=True, test_needs_autoincrement=True),
@@ -1499,6 +1503,12 @@ class OverrideColKeyTest(fixtures.MappedTest):
Column('base_id', Integer, ForeignKey('base.base_id'), primary_key=True),
Column('subdata', String(255))
)
+ subtable_two = Table('subtable_two', metadata,
+ Column('base_id', Integer, primary_key=True),
+ Column('fk_base_id', Integer, ForeignKey('base.base_id')),
+ Column('subdata', String(255))
+ )
+
def test_plain(self):
# control case
@@ -1609,6 +1619,23 @@ class OverrideColKeyTest(fixtures.MappedTest):
# an exception in 0.7 due to the implicit conflict.
assert_raises(sa_exc.InvalidRequestError, go)
+ def test_pk_fk_different(self):
+ class Base(object):
+ pass
+ class Sub(Base):
+ pass
+
+ mapper(Base, base)
+
+ def go():
+ mapper(Sub, subtable_two, inherits=Base)
+ assert_raises_message(
+ sa_exc.SAWarning,
+ "Implicitly combining column base.base_id with "
+ "column subtable_two.base_id under attribute 'base_id'",
+ go
+ )
+
def test_plain_descriptor(self):
"""test that descriptors prevent inheritance from propigating properties to subclasses."""
@@ -1716,12 +1743,12 @@ class OptimizedLoadTest(fixtures.MappedTest):
Table('sub', metadata,
Column('id', Integer, ForeignKey('base.id'), primary_key=True),
Column('sub', String(50)),
- Column('counter', Integer, server_default="1"),
- Column('counter2', Integer, server_default="1")
+ Column('subcounter', Integer, server_default="1"),
+ Column('subcounter2', Integer, server_default="1")
)
Table('subsub', metadata,
Column('id', Integer, ForeignKey('sub.id'), primary_key=True),
- Column('counter2', Integer, server_default="1")
+ Column('subsubcounter2', Integer, server_default="1")
)
Table('with_comp', metadata,
Column('id', Integer, ForeignKey('base.id'), primary_key=True),
@@ -1743,7 +1770,7 @@ class OptimizedLoadTest(fixtures.MappedTest):
mapper(Base, base)
mapper(JoinBase, base.outerjoin(sub), properties=util.OrderedDict(
[('id', [base.c.id, sub.c.id]),
- ('counter', [base.c.counter, sub.c.counter])])
+ ('counter', [base.c.counter, sub.c.subcounter])])
)
mapper(SubJoinBase, inherits=JoinBase)
@@ -1765,11 +1792,10 @@ class OptimizedLoadTest(fixtures.MappedTest):
go,
CompiledSQL(
"SELECT base.id AS base_id, sub.id AS sub_id, "
- "base.counter AS base_counter, sub.counter AS sub_counter, "
- "base.data AS base_data, "
- "base.type AS base_type, sub.sub AS sub_sub, "
- "sub.counter2 AS sub_counter2 FROM base "
- "LEFT OUTER JOIN sub ON base.id = sub.id "
+ "base.counter AS base_counter, sub.subcounter AS sub_subcounter, "
+ "base.data AS base_data, base.type AS base_type, "
+ "sub.sub AS sub_sub, sub.subcounter2 AS sub_subcounter2 "
+ "FROM base LEFT OUTER JOIN sub ON base.id = sub.id "
"WHERE base.id = :param_1",
{'param_1': sjb_id}
),
@@ -1914,14 +1940,14 @@ class OptimizedLoadTest(fixtures.MappedTest):
),
)
def go():
- eq_( s1.counter2, 1 )
+ eq_( s1.subcounter2, 1 )
self.assert_sql_execution(
testing.db,
go,
CompiledSQL(
- "SELECT sub.counter AS sub_counter, base.counter AS base_counter, "
- "sub.counter2 AS sub_counter2 FROM base JOIN sub ON "
- "base.id = sub.id WHERE base.id = :param_1",
+ "SELECT base.counter AS base_counter, sub.subcounter AS sub_subcounter, "
+ "sub.subcounter2 AS sub_subcounter2 FROM base JOIN sub "
+ "ON base.id = sub.id WHERE base.id = :param_1",
lambda ctx:{'param_1': s1.id}
),
)
@@ -1939,19 +1965,19 @@ class OptimizedLoadTest(fixtures.MappedTest):
s1 = Sub()
assert m._optimized_get_statement(attributes.instance_state(s1),
- ['counter2']) is None
+ ['subcounter2']) is None
# loads s1.id as None
eq_(s1.id, None)
# this now will come up with a value of None for id - should reject
assert m._optimized_get_statement(attributes.instance_state(s1),
- ['counter2']) is None
+ ['subcounter2']) is None
s1.id = 1
attributes.instance_state(s1)._commit_all(s1.__dict__, None)
assert m._optimized_get_statement(attributes.instance_state(s1),
- ['counter2']) is not None
+ ['subcounter2']) is not None
def test_load_expired_on_pending_twolevel(self):
base, sub, subsub = (self.tables.base,
@@ -1970,7 +1996,7 @@ class OptimizedLoadTest(fixtures.MappedTest):
mapper(Sub, sub, inherits=Base, polymorphic_identity='sub')
mapper(SubSub, subsub, inherits=Sub, polymorphic_identity='subsub')
sess = Session()
- s1 = SubSub(data='s1', counter=1)
+ s1 = SubSub(data='s1', counter=1, subcounter=2)
sess.add(s1)
self.assert_sql_execution(
testing.db,
@@ -1981,9 +2007,9 @@ class OptimizedLoadTest(fixtures.MappedTest):
[{'data':'s1','type':'subsub','counter':1}]
),
CompiledSQL(
- "INSERT INTO sub (id, sub, counter) VALUES "
- "(:id, :sub, :counter)",
- lambda ctx:[{'counter': 1, 'sub': None, 'id': s1.id}]
+ "INSERT INTO sub (id, sub, subcounter) VALUES "
+ "(:id, :sub, :subcounter)",
+ lambda ctx:[{'subcounter': 2, 'sub': None, 'id': s1.id}]
),
CompiledSQL(
"INSERT INTO subsub (id) VALUES (:id)",
@@ -1993,14 +2019,14 @@ class OptimizedLoadTest(fixtures.MappedTest):
def go():
eq_(
- s1.counter2, 1
+ s1.subcounter2, 1
)
self.assert_sql_execution(
testing.db,
go,
CompiledSQL(
- "SELECT subsub.counter2 AS subsub_counter2, "
- "sub.counter2 AS sub_counter2 FROM subsub, sub "
+ "SELECT subsub.subsubcounter2 AS subsub_subsubcounter2, "
+ "sub.subcounter2 AS sub_subcounter2 FROM subsub, sub "
"WHERE :param_1 = sub.id AND sub.id = subsub.id",
lambda ctx:{'param_1': s1.id}
),
diff --git a/test/orm/inheritance/test_manytomany.py b/test/orm/inheritance/test_manytomany.py
index e3d2c90de..ace90c7fa 100644
--- a/test/orm/inheritance/test_manytomany.py
+++ b/test/orm/inheritance/test_manytomany.py
@@ -154,11 +154,11 @@ class InheritTest3(fixtures.MappedTest):
bar = Table('bar', metadata,
Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
- Column('data', String(20)))
+ Column('bar_data', String(20)))
blub = Table('blub', metadata,
Column('id', Integer, ForeignKey('bar.id'), primary_key=True),
- Column('data', String(20)))
+ Column('blub_data', String(20)))
bar_foo = Table('bar_foo', metadata,
Column('bar_id', Integer, ForeignKey('bar.id')),
diff --git a/test/orm/test_cycles.py b/test/orm/test_cycles.py
index 59f8198f0..8e086ff88 100644
--- a/test/orm/test_cycles.py
+++ b/test/orm/test_cycles.py
@@ -275,16 +275,14 @@ class InheritTestTwo(fixtures.MappedTest):
def define_tables(cls, metadata):
Table('a', metadata,
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
- Column('data', String(30)),
Column('cid', Integer, ForeignKey('c.id')))
Table('b', metadata,
Column('id', Integer, ForeignKey("a.id"), primary_key=True),
- Column('data', String(30)))
+ )
Table('c', metadata,
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
- Column('data', String(30)),
Column('aid', Integer,
ForeignKey('a.id', use_alter=True, name="foo")))
diff --git a/test/orm/test_events.py b/test/orm/test_events.py
index 9c9acc6eb..f7667b9f1 100644
--- a/test/orm/test_events.py
+++ b/test/orm/test_events.py
@@ -41,7 +41,8 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
pass
mapper(A, users)
- mapper(B, addresses, inherits=A)
+ mapper(B, addresses, inherits=A,
+ properties={'address_id': addresses.c.id})
def init_a(target, args, kwargs):
canary.append(('init_a', target))
@@ -220,7 +221,8 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
pass
mapper(User, users)
- mapper(AdminUser, addresses, inherits=User)
+ mapper(AdminUser, addresses, inherits=User,
+ properties={'address_id': addresses.c.id})
canary1 = self.listen_all(User, propagate=True)
canary2 = self.listen_all(User)
@@ -264,7 +266,8 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
class AdminUser(User):
pass
- mapper(AdminUser, addresses, inherits=User)
+ mapper(AdminUser, addresses, inherits=User,
+ properties={'address_id': addresses.c.id})
canary3 = self.listen_all(AdminUser)
sess = create_session()
@@ -853,7 +856,8 @@ class RemovalTest(_fixtures.FixtureTest):
pass
mapper(User, users)
- mapper(AdminUser, addresses, inherits=User)
+ mapper(AdminUser, addresses, inherits=User,
+ properties={'address_id': addresses.c.id})
fn = Mock()
event.listen(User.name, "set", fn, propagate=True)
@@ -1594,7 +1598,8 @@ class MapperExtensionTest(_fixtures.FixtureTest):
pass
mapper(User, users, extension=Ext())
- mapper(AdminUser, addresses, inherits=User)
+ mapper(AdminUser, addresses, inherits=User,
+ properties={'address_id': addresses.c.id})
sess = create_session()
am = AdminUser(name='au1', email_address='au1@e1')
@@ -1670,7 +1675,8 @@ class MapperExtensionTest(_fixtures.FixtureTest):
ext = Ext()
mapper(User, users, extension=ext)
- mapper(AdminUser, addresses, inherits=User, extension=ext)
+ mapper(AdminUser, addresses, inherits=User, extension=ext,
+ properties={'address_id': addresses.c.id})
sess = create_session()
am = AdminUser(name="au1", email_address="au1@e1")
diff --git a/test/orm/test_inspect.py b/test/orm/test_inspect.py
index 5f5457943..ee3fe213e 100644
--- a/test/orm/test_inspect.py
+++ b/test/orm/test_inspect.py
@@ -71,7 +71,9 @@ class TestORMInspection(_fixtures.FixtureTest):
user_table = self.tables.users
addresses_table = self.tables.addresses
mapper(Foo, user_table, with_polymorphic=(Bar,))
- mapper(Bar, addresses_table, inherits=Foo)
+ mapper(Bar, addresses_table, inherits=Foo, properties={
+ 'address_id': addresses_table.c.id
+ })
i1 = inspect(Foo)
i2 = inspect(Foo)
assert i1.selectable is i2.selectable
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index 40891e0d8..e33c93977 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -348,7 +348,9 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
class Foo(User):pass
mapper(User, users)
- mapper(Foo, addresses, inherits=User)
+ mapper(Foo, addresses, inherits=User, properties={
+ 'address_id': addresses.c.id
+ })
assert getattr(Foo().__class__, 'name').impl is not None
def test_deferred_subclass_attribute_instrument(self):
@@ -359,7 +361,9 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
class Foo(User):pass
mapper(User, users)
configure_mappers()
- mapper(Foo, addresses, inherits=User)
+ mapper(Foo, addresses, inherits=User, properties={
+ 'address_id': addresses.c.id
+ })
assert getattr(Foo().__class__, 'name').impl is not None
def test_check_descriptor_as_method(self):
@@ -584,7 +588,9 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
class SubUser(User):
pass
m = mapper(User, users)
- m2 = mapper(SubUser, addresses, inherits=User)
+ m2 = mapper(SubUser, addresses, inherits=User, properties={
+ 'address_id': addresses.c.id
+ })
m3 = mapper(Address, addresses, properties={
'foo':relationship(m2)
})
@@ -697,7 +703,9 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
pass
m1 = mapper(User, users, polymorphic_identity='user')
m2 = mapper(AddressUser, addresses, inherits=User,
- polymorphic_identity='address')
+ polymorphic_identity='address', properties={
+ 'address_id': addresses.c.id
+ })
m3 = mapper(AddressUser, addresses, non_primary=True)
assert m3._identity_class is m2._identity_class
eq_(
diff --git a/test/orm/test_relationships.py b/test/orm/test_relationships.py
index 3d8287b75..f2bcd2036 100644
--- a/test/orm/test_relationships.py
+++ b/test/orm/test_relationships.py
@@ -1478,22 +1478,22 @@ class TypeMatchTest(fixtures.MappedTest):
Table("a", metadata,
Column('aid', Integer, primary_key=True,
test_needs_autoincrement=True),
- Column('data', String(30)))
+ Column('adata', String(30)))
Table("b", metadata,
Column('bid', Integer, primary_key=True,
test_needs_autoincrement=True),
Column("a_id", Integer, ForeignKey("a.aid")),
- Column('data', String(30)))
+ Column('bdata', String(30)))
Table("c", metadata,
Column('cid', Integer, primary_key=True,
test_needs_autoincrement=True),
Column("b_id", Integer, ForeignKey("b.bid")),
- Column('data', String(30)))
+ Column('cdata', String(30)))
Table("d", metadata,
Column('did', Integer, primary_key=True,
test_needs_autoincrement=True),
Column("a_id", Integer, ForeignKey("a.aid")),
- Column('data', String(30)))
+ Column('ddata', String(30)))
def test_o2m_oncascade(self):
a, c, b = (self.tables.a,
diff --git a/test/orm/test_unitofwork.py b/test/orm/test_unitofwork.py
index ada2e6c6f..3f785a58b 100644
--- a/test/orm/test_unitofwork.py
+++ b/test/orm/test_unitofwork.py
@@ -1408,7 +1408,9 @@ class SaveTest(_fixtures.FixtureTest):
# define a mapper for AddressUser that inherits the User.mapper, and
# joins on the id column
- mapper(AddressUser, addresses, inherits=m1)
+ mapper(AddressUser, addresses, inherits=m1, properties={
+ 'address_id': addresses.c.id
+ })
au = AddressUser(name='u', email_address='u@e')
@@ -2344,12 +2346,12 @@ class InheritingRowSwitchTest(fixtures.MappedTest):
@classmethod
def define_tables(cls, metadata):
Table('parent', metadata,
- Column('id', Integer, primary_key=True),
+ Column('pid', Integer, primary_key=True),
Column('pdata', String(30))
)
Table('child', metadata,
- Column('id', Integer, primary_key=True),
- Column('pid', Integer, ForeignKey('parent.id')),
+ Column('cid', Integer, primary_key=True),
+ Column('pid', Integer, ForeignKey('parent.pid')),
Column('cdata', String(30))
)
@@ -2371,27 +2373,27 @@ class InheritingRowSwitchTest(fixtures.MappedTest):
mapper(C, child, inherits=P)
sess = create_session()
- c1 = C(id=1, pdata='c1', cdata='c1')
+ c1 = C(pid=1, cid=1, pdata='c1', cdata='c1')
sess.add(c1)
sess.flush()
# establish a row switch between c1 and c2.
# c2 has no value for the "child" table
- c2 = C(id=1, pdata='c2')
+ c2 = C(pid=1, cid=1, pdata='c2')
sess.add(c2)
sess.delete(c1)
self.assert_sql_execution(testing.db, sess.flush,
- CompiledSQL("UPDATE parent SET pdata=:pdata WHERE parent.id = :parent_id",
- {'pdata':'c2', 'parent_id':1}
+ CompiledSQL("UPDATE parent SET pdata=:pdata WHERE parent.pid = :parent_pid",
+ {'pdata':'c2', 'parent_pid':1}
),
# this fires as of [ticket:1362], since we synchronzize
# PK/FKs on UPDATES. c2 is new so the history shows up as
# pure added, update occurs. If a future change limits the
# sync operation during _save_obj().update, this is safe to remove again.
- CompiledSQL("UPDATE child SET pid=:pid WHERE child.id = :child_id",
- {'pid':1, 'child_id':1}
+ CompiledSQL("UPDATE child SET pid=:pid WHERE child.cid = :child_cid",
+ {'pid':1, 'child_cid':1}
)
)