0.5.0rc2
========
- orm
+ - Fixed bug involving read/write relation()s that
+ contain literal or other non-column expressions
+ within their primaryjoin condition equated
+ to a foreign key column.
+
- "non-batch" mode in mapper(), a feature which allows
mapper extension methods to be called as each instance
is updated/inserted, now honors the insert order
if prop:
raise exc.UnmappedColumnError("Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop)))
else:
- raise exc.UnmappedColumnError("No column %s.%s is configured on mapper %s..." % (column.table.name, column.name, str(self)))
+ raise exc.UnmappedColumnError("No column %s is configured on mapper %s..." % (column, self))
# TODO: improve names
def _get_state_attr_by_column(self, state, column):
self.synchronize_pairs.append((r, l))
else:
eq_pairs = criterion_as_pairs(self.primaryjoin, consider_as_foreign_keys=self._foreign_keys, any_operator=self.viewonly)
- eq_pairs = [(l, r) for l, r in eq_pairs if (self._col_is_part_of_mappings(l) and self._col_is_part_of_mappings(r)) or r in self._foreign_keys]
+ eq_pairs = [(l, r) for l, r in eq_pairs if (self._col_is_part_of_mappings(l) and self._col_is_part_of_mappings(r)) or self.viewonly and r in self._foreign_keys]
if not eq_pairs:
if not self.viewonly and criterion_as_pairs(self.primaryjoin, consider_as_foreign_keys=self._foreign_keys, any_operator=True):
for old, new in zip(con.lineItems, newcon.lineItems):
assert old.id == new.id
+class RelationTest6(_base.MappedTest):
+ """test a relation with a non-column entity in the primary join,
+ is not viewonly, and also has the non-column's clause mentioned in the
+ foreign keys list.
+
+ """
+
+ def define_tables(self, metadata):
+ Table('tags', metadata, Column("id", Integer, primary_key=True),
+ Column("data", Integer),
+ )
+
+ Table('tag_foo', metadata,
+ Column("id", Integer, primary_key=True),
+ Column('tagid', Integer),
+ Column("data", Integer),
+ )
+ @testing.resolve_artifact_names
+ def test_basic(self):
+ class Tag(_base.ComparableEntity):
+ pass
+ class TagInstance(_base.ComparableEntity):
+ pass
+
+ mapper(Tag, tags, properties={
+ 'foo':relation(TagInstance,
+ primaryjoin=sa.and_(tag_foo.c.data=='iplc_case',
+ tag_foo.c.tagid==tags.c.id),
+ foreign_keys=[tag_foo.c.tagid, tag_foo.c.data],
+ ),
+ })
+
+ mapper(TagInstance, tag_foo)
+
+ sess = create_session()
+ t1 = Tag(data='some tag')
+ t1.foo.append(TagInstance(data='iplc_case'))
+ t1.foo.append(TagInstance(data='not_iplc_case'))
+ sess.add(t1)
+ sess.flush()
+ sess.clear()
+
+ # relation works
+ eq_(sess.query(Tag).all(), [Tag(data='some tag', foo=[TagInstance(data='iplc_case')])])
+
+ # both TagInstances were persisted
+ eq_(
+ sess.query(TagInstance).order_by(TagInstance.data).all(),
+ [TagInstance(data='iplc_case'), TagInstance(data='not_iplc_case')]
+ )
+
class TypeMatchTest(_base.MappedTest):
"""test errors raised when trying to add items whose type is not handled by a relation"""