diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 10 | ||||
-rw-r--r-- | test/engine/reflection.py | 24 | ||||
-rw-r--r-- | test/orm/expire.py | 12 |
4 files changed, 48 insertions, 4 deletions
@@ -4,7 +4,11 @@ CHANGES 0.4.2p4 ------ - +- orm + - proper error message is raised when trying to + access expired instance attributes with no session + present + - dialects - finally added PGMacAddr type to postgres [ticket:580] diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 19e9c35e9..dcfae524f 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1529,8 +1529,16 @@ def _load_scalar_attributes(instance, attribute_names): global object_session if not object_session: from sqlalchemy.orm.session import object_session + + session = object_session(instance) + mapper = object_mapper(instance) + if not session: + try: + session = mapper.get_session() + except exceptions.InvalidRequestError: + raise exceptions.InvalidRequestError("Instance %s is not bound to a Session, and no contextual session is established; attribute refresh operation cannot proceed" % (instance.__class__)) - if object_session(instance).query(object_mapper(instance))._get(instance._instance_key, refresh_instance=instance._state, only_load_props=attribute_names) is None: + if session.query(mapper)._get(instance._instance_key, refresh_instance=instance._state, only_load_props=attribute_names) is None: raise exceptions.InvalidRequestError("Could not refresh instance '%s'" % instance_str(instance)) def _state_mapper(state, entity_name=None): diff --git a/test/engine/reflection.py b/test/engine/reflection.py index a3b42bf6e..ea56e315b 100644 --- a/test/engine/reflection.py +++ b/test/engine/reflection.py @@ -129,8 +129,8 @@ class ReflectionTest(PersistTest): meta.drop_all() def test_override_create_fkcols(self): - """test that you can override columns and create new foreign keys to other reflected tables. - this is common with MySQL MyISAM tables.""" + """test that you can override columns and create new foreign keys to other reflected tables + which have no foreign keys. this is common with MySQL MyISAM tables.""" meta = MetaData(testbase.db) users = Table('users', meta, @@ -184,6 +184,7 @@ class ReflectionTest(PersistTest): finally: meta.drop_all() + def test_unknown_types(self): meta = MetaData(testbase.db) t = Table("test", meta, @@ -299,6 +300,25 @@ class ReflectionTest(PersistTest): assert [c.parent for c in a2.c.user_id.foreign_keys] == [a2.c.user_id] assert list(a2.c.user_id.foreign_keys)[0].parent is a2.c.user_id assert u2.join(a2).onclause == u2.c.id==a2.c.user_id + + meta2 = MetaData(testbase.db) + u2 = Table('users', meta2, + Column('id', Integer, primary_key=True), + autoload=True) + a2 = Table('addresses', meta2, + Column('id', Integer, primary_key=True), + Column('user_id',Integer, ForeignKey('users.id')), + autoload=True) + + assert len(a2.foreign_keys) == 1 + assert len(a2.c.user_id.foreign_keys) == 1 + assert len(a2.constraints) == 2 + assert [c.parent for c in a2.foreign_keys] == [a2.c.user_id] + assert [c.parent for c in a2.c.user_id.foreign_keys] == [a2.c.user_id] + assert list(a2.c.user_id.foreign_keys)[0].parent is a2.c.user_id + assert u2.join(a2).onclause == u2.c.id==a2.c.user_id + + finally: meta.drop_all() diff --git a/test/orm/expire.py b/test/orm/expire.py index 2b25c5ba9..d54e9fc2d 100644 --- a/test/orm/expire.py +++ b/test/orm/expire.py @@ -64,6 +64,18 @@ class ExpireTest(FixtureTest): sess.clear() assert sess.query(User).get(7).name == 'somenewname' + def test_no_session(self): + mapper(User, users) + sess = create_session() + u = sess.query(User).get(7) + + sess.expire(u, attribute_names=['name']) + sess.expunge(u) + try: + u.name + except exceptions.InvalidRequestError, e: + assert str(e) == "Instance <class 'testlib.fixtures.User'> is not bound to a Session, and no contextual session is established; attribute refresh operation cannot proceed" + def test_expire_preserves_changes(self): """test that the expire load operation doesn't revert post-expire changes""" |