union(query1, query2), select([foo]).select_from(query),
etc.
+ - a session.expire() on a particular collection attribute
+ will clear any pending backref additions as well, so that
+ the next access correctly returns only what was present
+ in the database. Presents some degree of a workaround for
+ [ticket:1315], although we are considering removing the
+ flush([objects]) feature altogether.
+
- improvements to the "determine direction" logic of
relation() such that the direction of tricky situations
like mapper(A.join(B)) -> relation-> mapper(B) can be
state.commit([self.key])
if self.key in state.pending:
+
# pending items exist. issue a modified event,
# add/remove new items.
state.modified_event(self, True, user_data)
if impl.accepts_scalar_loader:
self.callables[key] = self
self.dict.pop(key, None)
+ self.pending.pop(key, None)
self.committed_state.pop(key, None)
def reset(self, key):
print attributes.instance_state(u).dict
assert u.addresses[0].email_address == 'ed@wood.com'
+ @testing.resolve_artifact_names
+ def test_expired_pending(self):
+ mapper(User, users, properties={
+ 'addresses':relation(Address, backref='user'),
+ })
+ mapper(Address, addresses)
+
+ sess = create_session()
+ a1 = Address(email_address='a1')
+ sess.add(a1)
+ sess.flush()
+
+ u1 = User(name='u1')
+ a1.user = u1
+ sess.flush()
+
+ # expire 'addresses'. backrefs
+ # which attach to u1 will expect to be "pending"
+ sess.expire(u1, ['addresses'])
+
+ # attach an Address. now its "pending"
+ # in user.addresses
+ a2 = Address(email_address='a2')
+ a2.user = u1
+
+ # expire u1.addresses again. this expires
+ # "pending" as well.
+ sess.expire(u1, ['addresses'])
+
+ # insert a new row
+ sess.execute(addresses.insert(), dict(email_address='a3', user_id=u1.id))
+
+ # only two addresses pulled from the DB, no "pending"
+ assert len(u1.addresses) == 2
+
+ sess.flush()
+ sess.expire_all()
+ assert len(u1.addresses) == 3
+
@testing.resolve_artifact_names
def test_expired_lazy(self):
mapper(User, users, properties={