- a forward and complementing backwards reference which are both

of the same direction, i.e. ONETOMANY or MANYTOONE,
is now detected, and an error message is raised.
Saves crazy CircularDependencyErrors later on.
This commit is contained in:
Mike Bayer
2009-03-09 01:20:29 +00:00
parent 1b5d224df5
commit 68ee348d36
4 changed files with 68 additions and 2 deletions
+6 -1
View File
@@ -42,7 +42,12 @@ CHANGES
- Added "post_configure_attribute" method to InstrumentationManager,
so that the "listen_for_events.py" example works again.
[ticket:1314]
- a forward and complementing backwards reference which are both
of the same direction, i.e. ONETOMANY or MANYTOONE,
is now detected, and an error message is raised.
Saves crazy CircularDependencyErrors later on.
- Fixed bugs in Query regarding simultaneous selection of
multiple joined-table inheritance entities with common base
classes:
+4
View File
@@ -703,6 +703,10 @@ class RelationProperty(StrategizedProperty):
raise sa_exc.ArgumentError("reverse_property %r on relation %s references "
"relation %s, which does not reference mapper %s" % (key, self, other, self.parent))
if self.direction in (ONETOMANY, MANYTOONE) and self.direction == other.direction:
raise sa_exc.ArgumentError("%s and back-reference %s are both of the same direction %r."
" Did you mean to set remote_side on the many-to-one side ?" % (self, other, self.direction))
def do_init(self):
self._get_target()
self._process_dependent_arguments()
+1 -1
View File
@@ -447,7 +447,7 @@ class MapperTest(_fixtures.FixtureTest):
include_properties=('id', 'type', 'name'))
e_m = mapper(Employee, inherits=p_m, polymorphic_identity='employee',
properties={
'boss': relation(Manager, backref='peon')
'boss': relation(Manager, backref=backref('peon', ), remote_side=t.c.id)
},
exclude_properties=('vendor_id',))
+57
View File
@@ -1519,7 +1519,64 @@ class ExplicitLocalRemoteTest(_base.MappedTest):
mapper(T2, t2)
self.assertRaises(sa.exc.ArgumentError, sa.orm.compile_mappers)
class InvalidRemoteSideTest(_base.MappedTest):
def define_tables(self, metadata):
Table('t1', metadata,
Column('id', Integer, primary_key=True),
Column('data', String(50)),
Column('t_id', Integer, ForeignKey('t1.id'))
)
@testing.resolve_artifact_names
def setup_classes(self):
class T1(_base.ComparableEntity):
pass
@testing.resolve_artifact_names
def test_o2m_backref(self):
mapper(T1, t1, properties={
't1s':relation(T1, backref='parent')
})
self.assertRaisesMessage(sa.exc.ArgumentError, "T1.t1s and back-reference T1.parent are "
"both of the same direction <symbol 'ONETOMANY>. Did you "
"mean to set remote_side on the many-to-one side ?", sa.orm.compile_mappers)
@testing.resolve_artifact_names
def test_m2o_backref(self):
mapper(T1, t1, properties={
't1s':relation(T1, backref=backref('parent', remote_side=t1.c.id), remote_side=t1.c.id)
})
self.assertRaisesMessage(sa.exc.ArgumentError, "T1.t1s and back-reference T1.parent are "
"both of the same direction <symbol 'MANYTOONE>. Did you "
"mean to set remote_side on the many-to-one side ?", sa.orm.compile_mappers)
@testing.resolve_artifact_names
def test_o2m_explicit(self):
mapper(T1, t1, properties={
't1s':relation(T1, back_populates='parent'),
'parent':relation(T1, back_populates='t1s'),
})
# can't be sure of ordering here
self.assertRaisesMessage(sa.exc.ArgumentError,
"both of the same direction <symbol 'ONETOMANY>. Did you "
"mean to set remote_side on the many-to-one side ?", sa.orm.compile_mappers)
@testing.resolve_artifact_names
def test_m2o_explicit(self):
mapper(T1, t1, properties={
't1s':relation(T1, back_populates='parent', remote_side=t1.c.id),
'parent':relation(T1, back_populates='t1s', remote_side=t1.c.id)
})
# can't be sure of ordering here
self.assertRaisesMessage(sa.exc.ArgumentError,
"both of the same direction <symbol 'MANYTOONE>. Did you "
"mean to set remote_side on the many-to-one side ?", sa.orm.compile_mappers)
class InvalidRelationEscalationTest(_base.MappedTest):
def define_tables(self, metadata):