Commits

Mike Bayer committed f8691c7

- Query.UpdateDeleteTest.test_delete_fallback fails on mysql due to subquery in DELETE; not sure how to do this exact operation in MySQL
- added query_cls keyword argument to sessionmaker(); allows user-defined Query subclasses to be generated by query().
- added @attributes.on_reconstitute decorator, MapperExtension.on_reconstitute, both receieve 'on_load' attribute event allowing
non-__init__ dependent instance initialization routines.
- push memusage to the top to avoid pointless heisenbugs
- renamed '_foostate'/'_fooclass_manager' to '_sa_instance_state'/'_sa_class_manager'
- removed legacy instance ORM state accessors
- query._get() will use _remove_newly_deleted instead of expunge() on ObjectDeleted, so that transaction rollback
restores the previous state
- removed MapperExtension.get(); replaced by a user-defined Query subclass
- removed needless **kwargs from query.get()
- removed Session.get(cls, id); this is redundant against Session.query(cls).get(id)
- removed Query.load() and Session.load(); the use case for this method has never been clear, and the same functionality is available in more explicit ways

Comments (0)

Files changed (18)

examples/query_caching/query_caching.py

         else:
             return Query.__iter__(self)
 
-# currently the easiest way to get a custom Query class in the mix is just 
-# to subclass Session.  A decorated sessionmaker() would probably work too.
-class CacheableSession(Session):
-    def __init__(self, **kwargs):
-        super(CacheableSession, self).__init__(**kwargs)
-        self._query_cls = CachingQuery
-        
-        
 # example usage
 if __name__ == '__main__':
     from sqlalchemy import Column, create_engine, Integer, String
     from sqlalchemy.orm import sessionmaker
     from sqlalchemy.ext.declarative import declarative_base
     
-    Session = sessionmaker(class_=CacheableSession)
+    Session = sessionmaker(query_cls=CachingQuery)
     
     Base = declarative_base(engine=create_engine('sqlite://', echo=True))
     

lib/sqlalchemy/orm/attributes.py

             fn(*args, **kwargs)
 
     def add_listener(self, event, listener):
-        # not thread safe... problem?
+        # not thread safe... problem?  mb: nope
         bucket = getattr(self, event)
         if bucket == ():
             setattr(self, event, [listener])
 class ClassManager(dict):
     """tracks state information at the class level."""
 
-    MANAGER_ATTR = '_fooclass_manager'
-    STATE_ATTR = '_foostate'
+    MANAGER_ATTR = '_sa_class_manager'
+    STATE_ATTR = '_sa_instance_state'
 
     event_registry_factory = Events
     instance_state_factory = InstanceState
         self._instantiable = False
         self.events = self.event_registry_factory()
 
+        for meth in class_.__dict__.values():
+            if hasattr(meth, '_sa_reconstitute'):
+                self.events.add_listener('on_load', meth)
+
     def instantiable(self, boolean):
         # experiment, probably won't stay in this form
         assert boolean ^ self._instantiable, (boolean, self._instantiable)
 def is_instrumented(instance, key):
     return manager_of_class(instance.__class__).is_instrumented(key, search=True)
 
+def on_reconstitute(fn):
+    """Decorate a method as the 'reconstitute' hook.
+    
+    This method will be called based on the 'on_load' event hook.
+    
+    Note that when using ORM mappers, this method is equivalent
+    to MapperExtension.on_reconstitute().
+
+    """
+    fn._sa_reconstitute = True
+    return fn
+    
+    
 class InstrumentationRegistry(object):
     """Private instrumentation registration singleton."""
 

lib/sqlalchemy/orm/interfaces.py

     def init_failed(self, mapper, class_, oldinit, instance, args, kwargs):
         return EXT_CONTINUE
 
-    def load(self, query, *args, **kwargs):
-        """Override the `load` method of the Query object.
-
-        The return value of this method is used as the result of
-        ``query.load()`` if the value is anything other than EXT_CONTINUE.
-        """
-
-        return EXT_CONTINUE
-
-    def get(self, query, *args, **kwargs):
-        """Override the `get` method of the Query object.
-
-        The return value of this method is used as the result of
-        ``query.get()`` if the value is anything other than EXT_CONTINUE.
-        """
-
-        return EXT_CONTINUE
-
     def translate_row(self, mapper, context, row):
         """Perform pre-processing on the given result row and return a
         new row instance.
 
-        This is called as the very first step in the ``_instance()``
-        method.
+        This is called when the mapper first receives a row, before 
+        the object identity or the instance itself has been derived
+        from that row.
+        
         """
-
         return EXT_CONTINUE
 
     def create_instance(self, mapper, selectcontext, row, class_):
 
         return value
           A new object instance, or EXT_CONTINUE
+
         """
-
         return EXT_CONTINUE
 
     def append_result(self, mapper, selectcontext, row, instance, result, **flags):
 
         \**flags
           extra information about the row, same as criterion in
-          `create_row_processor()` method of [sqlalchemy.orm.interfaces#MapperProperty]
+          ``create_row_processor()`` method of [sqlalchemy.orm.interfaces#MapperProperty]
         """
 
         return EXT_CONTINUE
 
     def populate_instance(self, mapper, selectcontext, row, instance, **flags):
-        """Receive a newly-created instance before that instance has
+        """Receive an instance before that instance has
         its attributes populated.
+        
+        This usually corresponds to a newly loaded instance but may
+        also correspond to an already-loaded instance which has
+        unloaded attributes to be populated.  The method may be 
+        called many times for a single instance, as multiple
+        result rows are used to populate eagerly loaded collections.
 
-        The normal population of attributes is according to each
-        attribute's corresponding MapperProperty (which includes
-        column-based attributes as well as relationships to other
-        classes).  If this method returns EXT_CONTINUE, instance
+        If this method returns EXT_CONTINUE, instance
         population will proceed normally.  If any other value or None
         is returned, instance population will not proceed, giving this
         extension an opportunity to populate the instance itself, if
         desired.
+        
+        As of 0.5, most usages of this hook are obsolete.  
+        For a generic "object has been newly created from a row" hook, 
+        use ``on_reconstitute()``, or the @attributes.on_reconstitute 
+        decorator.
+        
         """
+        return EXT_CONTINUE
 
+    def on_reconstitute(self, mapper, instance):
+        """Receive an object instance after it has been created via 
+        ``__new__()``, and after initial attribute population has
+        occurred.  
+        
+        This typicically occurs when the instance is created based 
+        on incoming result rows, and is only called once for that
+        instance's lifetime.
+        
+        Note that during a result-row load, this method is called upon
+        the first row received for this instance; therefore, if eager loaders
+        are to further populate collections on the instance, those will
+        *not* have been completely loaded as of yet.
+        
+        """
         return EXT_CONTINUE
 
     def before_insert(self, mapper, connection, instance):

lib/sqlalchemy/orm/mapper.py

         if not self.non_primary and self.entity_name in mappers:
             del mappers[self.entity_name]
         if not mappers and manager.info.get(_INSTRUMENTOR, False):
-            for legacy in _legacy_descriptors.keys():
-                manager.uninstall_member(legacy)
             manager.events.remove_listener('on_init', _event_on_init)
             manager.events.remove_listener('on_init_failure',
                                            _event_on_init_failure)
         event_registry = manager.events
         event_registry.add_listener('on_init', _event_on_init)
         event_registry.add_listener('on_init_failure', _event_on_init_failure)
+        if 'on_reconstitute' in self.extension.methods:
+            def reconstitute(instance):
+                self.extension.on_reconstitute(self, instance)
+            event_registry.add_listener('on_load', reconstitute)
 
-        for key, impl in _legacy_descriptors.items():
-            manager.install_member(key, impl)
 
         manager.info[_INSTRUMENTOR] = self
 
                     if instance is EXT_CONTINUE:
                         instance = self.class_manager.new_instance()
                     else:
-                        manager = attributes.manager_for_cls(instance.__class__)
+                        # TODO: don't think theres coverage here
+                        manager = attributes.manager_of_class(instance.__class__)
                         # TODO: if manager is None, raise a friendly error about
                         # returning instances of unmapped types
                         manager.setup_instance(instance)
                     if not populate_instance or extension.populate_instance(self, context, row, instance, only_load_props=attrs, instancekey=identitykey, isnew=isnew) is EXT_CONTINUE:
                         populate_state(state, row, isnew, attrs, instancekey=identitykey)
 
+            if loaded_instance:
+                state._run_on_load(instance)
+
             if result is not None and (not append_result or extension.append_result(self, context, row, instance, result, instancekey=identitykey, isnew=isnew) is EXT_CONTINUE):
                 result.append(instance)
 
-            if loaded_instance:
-                state._run_on_load(instance)
-
             return instance
         return _instance
 
             instrumenting_mapper, instrumenting_mapper.class_,
             state.manager.events.original_init, instance, args, kwargs)
 
-def _legacy_descriptors():
-    """Build compatibility descriptors mapping legacy to InstanceState.
-
-    These are slated for removal in 0.5.  They were never part of the
-    official public API but were suggested as temporary workarounds in a
-    number of mailing list posts.  Permanent and public solutions for those
-    needs should be available now.  Consult the applicable mailing list
-    threads for details.
-
-    """
-    def _instance_key(self):
-        state = attributes.instance_state(self)
-        if state.key is not None:
-            return state.key
-        else:
-            raise AttributeError("_instance_key")
-    _instance_key = util.deprecated(None, False)(_instance_key)
-    _instance_key = property(_instance_key)
-
-    def _sa_session_id(self):
-        state = attributes.instance_state(self)
-        if state.session_id is not None:
-            return state.session_id
-        else:
-            raise AttributeError("_sa_session_id")
-    _sa_session_id = util.deprecated(None, False)(_sa_session_id)
-    _sa_session_id = property(_sa_session_id)
-
-    def _entity_name(self):
-        state = attributes.instance_state(self)
-        if state.entity_name is attributes.NO_ENTITY_NAME:
-            return None
-        else:
-            return state.entity_name
-    _entity_name = util.deprecated(None, False)(_entity_name)
-    _entity_name = property(_entity_name)
-
-    return dict(locals())
-_legacy_descriptors = _legacy_descriptors()
 
 def _load_scalar_attributes(state, attribute_names):
     mapper = _state_mapper(state)

lib/sqlalchemy/orm/query.py

         self._yield_per = count
     yield_per = _generative()(yield_per)
 
-    def get(self, ident, **kwargs):
+    def get(self, ident):
         """Return an instance of the object based on the given identifier, or None if not found.
 
         The `ident` argument is a scalar or tuple of primary key column values
 
         """
 
-        ret = self._extension_zero().get(self, ident, **kwargs)
-        if ret is not mapper.EXT_CONTINUE:
-            return ret
-
         # convert composite types to individual args
         if hasattr(ident, '__composite_values__'):
             ident = ident.__composite_values__()
 
         key = self._only_mapper_zero().identity_key_from_primary_key(ident)
-        return self._get(key, ident, **kwargs)
-
-    def load(self, ident, raiseerr=True, **kwargs):
-        """Return an instance of the object based on the given identifier.
-
-        If not found, raises an exception.  The method will **remove all
-        pending changes** to the object already existing in the Session.  The
-        `ident` argument is a scalar or tuple of primary key column values in
-        the order of the table def's primary key columns.
-
-        """
-        ret = self._extension_zero().load(self, ident, **kwargs)
-        if ret is not mapper.EXT_CONTINUE:
-            return ret
-
-        # convert composite types to individual args
-        if hasattr(ident, '__composite_values__'):
-            ident = ident.__composite_values__()
-
-        key = self._only_mapper_zero().identity_key_from_primary_key(ident)
-        instance = self.populate_existing()._get(key, ident, **kwargs)
-        if instance is None and raiseerr:
-            raise sa_exc.InvalidRequestError("No instance found for identity %s" % repr(ident))
-        return instance
+        return self._get(key, ident)
 
     def query_from_parent(cls, instance, property, **kwargs):
         """Return a new Query with criterion corresponding to a parent instance.
                     try:
                         state()
                     except orm_exc.ObjectDeletedError:
-                        # TODO: should we expunge ?  if so, should we expunge here ? or in mapper._load_scalar_attributes ?
-                        self.session.expunge(instance)
+                        self.session._remove_newly_deleted(state)
                         return None
                 return instance
             except KeyError:

lib/sqlalchemy/orm/session.py

       called. This allows each database to roll back the entire transaction,
       before each transaction is committed.
 
+    query_cls
+      Class which should be used to create new Query objects, as returned
+      by the ``query()`` method.  Defaults to [sqlalchemy.orm.query#Query].
+      
     weak_identity_map
       When set to the default value of ``False``, a weak-referencing map is
       used; instances which are not externally referenced will be garbage
     public_methods = (
         '__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
         'clear', 'close', 'commit', 'connection', 'delete', 'execute', 'expire',
-        'expire_all', 'expunge', 'flush', 'get', 'get_bind', 'is_modified',
-        'load', 'merge', 'query', 'refresh', 'rollback', 'save',
+        'expire_all', 'expunge', 'flush', 'get_bind', 'is_modified',
+        'merge', 'query', 'refresh', 'rollback', 'save',
         'save_or_update', 'scalar', 'update')
 
     def __init__(self, bind=None, autoflush=True, autoexpire=True,
                  autocommit=False, twophase=False, echo_uow=False,
-                 weak_identity_map=True, binds=None, extension=None):
+                 weak_identity_map=True, binds=None, extension=None, query_cls=query.Query):
         """Construct a new Session.
 
         Arguments to ``Session`` are described using the
         self.autoexpire = autoexpire
         self.twophase = twophase
         self.extension = extension
-        self._query_cls = query.Query
+        self._query_cls = query_cls
         self._mapper_flush_opts = {}
 
         if binds is not None:
         for state in states:
             state.commit_all()
 
-    def get(self, class_, ident, entity_name=None):
-        """Return the instance of class with ident or None.
-
-        The `ident` argument is a scalar or tuple of primary key column values
-        in the order of the table def's primary key columns.
-
-        The `entity_name` keyword argument may also be specified which further
-        qualifies the underlying Mapper used to perform the query.
-
-        """
-        return self.query(_class_to_mapper(class_, entity_name)).get(ident)
-
-        return self.query(class_, entity_name=entity_name).get(ident)
-
-    def load(self, class_, ident, entity_name=None):
-        """Reset and return the instance of class with ident or raise.
-
-        If not found, raises an exception.  The method will **remove all
-        pending changes** to the object already existing in the ``Session``.
-        The `ident` argument is a scalar or tuple of primary key columns in
-        the order of the table def's primary key columns.
-
-        The `entity_name` keyword argument may also be specified which further
-        qualifies the underlying ``Mapper`` used to perform the query.
-
-        """
-        return self.query(_class_to_mapper(class_, entity_name)).load(ident)
-
     def refresh(self, instance, attribute_names=None):
         """Refresh the attributes on the given instance.
 
                 self._update_impl(merged_state)
                 new_instance = True
             else:
-                merged = self.get(mapper.class_, key[1])
+                merged = self.query(mapper.class_).get(key[1])
 
         if merged is None:
             merged = mapper.class_manager.new_instance()

test/orm/alltests.py

 
 def suite():
     modules_to_test = (
+    'orm.memusage',
         'orm.attributes',
         'orm.bind',
         'orm.extendedattr',
         'orm.association',
         'orm.merge',
         'orm.pickled',
-        'orm.memusage',
         'orm.utils',
 
         'orm.cycles',

test/orm/attributes.py

         # no lazyload occurs so this allows overwrite operation to proceed
         f = Foo()
         eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([], [], []))
-        print f._foostate.committed_state
         f.someattr = None
-        print f._foostate.committed_state, f._foostate.dict
         eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([None], [], []))
 
         f = Foo()
                 f = Foo()
                 sess.save(f)
                 sess.flush()
-                assert sess.get(Foo, f.id) is f
+                assert sess.query(Foo).get(f.id) is f
             finally:
                 if hasattr(bind, 'close'):
                     bind.close()

test/orm/deprecations.py

 import testenv; testenv.configure_for_tests()
 from testlib import testing
 from testlib.sa import Table, Column, Integer, String, ForeignKey, func
-from testlib.sa.orm import mapper, relation, create_session
+from testlib.sa.orm import mapper, relation, create_session, sessionmaker
 from orm import _base
 
 
     ######################################################################
 
     @testing.resolve_artifact_names
+    def test_override_get(self):
+        """MapperExtension.get()
+        
+        x = session.query.get(5)
+        
+        """
+        from sqlalchemy.orm.query import Query
+        cache = {}
+        class MyQuery(Query):
+            def get(self, ident, **kwargs):
+                if ident in cache:
+                    return cache[ident]
+                else:
+                    x = super(MyQuery, self).get(ident)
+                    cache[ident] = x
+                    return x
+                    
+        session = sessionmaker(query_cls=MyQuery)()
+        
+        ad1 = session.query(Address).get(1)
+        assert ad1 in cache.values()
+    
+    @testing.resolve_artifact_names
+    def test_load(self):
+        """x = session.query(Address).load(1)
+            
+            x = session.load(Address, 1)
+        
+        """
+
+        session = create_session()
+        ad1 = session.query(Address).populate_existing().get(1)
+        assert bool(ad1)
+        
+        
+    @testing.resolve_artifact_names
     def test_apply_max(self):
         """Query.apply_max(col)
 

test/orm/expire.py

     def test_persistence_check(self):
         mapper(User, users)
         s = create_session()
-        u = s.get(User, 7)
+        u = s.query(User).get(7)
         s.clear()
 
         self.assertRaisesMessage(sa.exc.InvalidRequestError, r"is not persistent within this Session", s.expire, u)
     @testing.resolve_artifact_names
     def test_get_refreshes(self):
         mapper(User, users)
-        s = create_session()
-        u = s.get(User, 10)
+        s = create_session(autocommit=False)
+        u = s.query(User).get(10)
         s.expire_all()
 
         def go():
-            u = s.get(User, 10)  # get() refreshes
+            u = s.query(User).get(10)  # get() refreshes
         self.assert_sql_count(testing.db, go, 1)
         def go():
             self.assertEquals(u.name, 'chuck')  # attributes unexpired
         self.assert_sql_count(testing.db, go, 0)
         def go():
-            u = s.get(User, 10)  # expire flag reset, so not expired
+            u = s.query(User).get(10)  # expire flag reset, so not expired
         self.assert_sql_count(testing.db, go, 0)
 
         s.expire_all()
-        users.delete().where(User.id==10).execute()
+        s.execute(users.delete().where(User.id==10))
 
-        # object is gone, get() returns None
+        # object is gone, get() returns None, removes u from session
         assert u in s
-        assert s.get(User, 10) is None
+        assert s.query(User).get(10) is None
         assert u not in s # and expunges
 
         # add it back
         # nope, raises ObjectDeletedError
         self.assertRaises(sa.orm.exc.ObjectDeletedError, getattr, u, 'name')
 
+        # do a get()/remove u from session again
+        assert s.query(User).get(10) is None
+        assert u not in s
+        
+        s.rollback()
+
+        assert u in s
+        # but now its back, rollback has occured, the _remove_newly_deleted
+        # is reverted
+        self.assertEquals(u.name, 'chuck')
+        
     @testing.resolve_artifact_names
     def test_refresh_cancels_expire(self):
         mapper(User, users)
         s = create_session()
-        u = s.get(User, 7)
+        u = s.query(User).get(7)
         s.expire(u)
         s.refresh(u)
 
         def go():
-            u = s.get(User, 7)
+            u = s.query(User).get(7)
             self.assertEquals(u.name, 'jack')
         self.assert_sql_count(testing.db, go, 0)
 
         })
         mapper(Address, addresses)
         s = create_session()
-        u = s.get(User, 8)
+        u = s.query(User).get(8)
         assert u.addresses[0].email_address == 'ed@wood.com'
 
         u.addresses[0].email_address = 'someotheraddress'
             'addresses':relation(mapper(Address, addresses), backref='user')
         })
         s = create_session()
-        u = s.get(User, 7)
+        u = s.query(User).get(7)
         u.name = 'foo'
         a = Address()
         assert sa.orm.object_session(a) is None
     def test_persistence_check(self):
         mapper(User, users)
         s = create_session()
-        u = s.get(User, 7)
+        u = s.query(User).get(7)
         s.clear()
         self.assertRaisesMessage(sa.exc.InvalidRequestError, r"is not persistent within this Session", lambda: s.refresh(u))
 
     def test_refresh_expired(self):
         mapper(User, users)
         s = create_session()
-        u = s.get(User, 7)
+        u = s.query(User).get(7)
         s.expire(u)
         assert 'name' not in u.__dict__
         s.refresh(u)
         })
 
         s = create_session()
-        u = s.get(User, 8)
+        u = s.query(User).get(8)
         assert len(u.addresses) == 3
         s.refresh(u)
         assert len(u.addresses) == 3
 
         s = create_session()
-        u = s.get(User, 8)
+        u = s.query(User).get(8)
         assert len(u.addresses) == 3
         s.expire(u)
         assert len(u.addresses) == 3

test/orm/extendedattr.py

         self.assertRaises((AttributeError, KeyError),
                           attributes.instance_state, None)
 
+class ReconstituteTest(testing.TestBase):
+    def test_on_reconstitute(self):
+        recon = []
+        class MyClass(object):
+            @attributes.on_reconstitute
+            def recon(self):
+                recon.append('go')
+        
+        attributes.register_class(MyClass)
+        m = attributes.manager_of_class(MyClass).new_instance()
+        s = attributes.instance_state(m)
+        s._run_on_load(m)
+        assert recon == ['go']
 
 if __name__ == '__main__':
     testing.main()

test/orm/mapper.py

         self.assertRaises(NotImplementedError,
                           getattr, sa.orm.class_mapper(User), 'properties')
 
-    @testing.uses_deprecated(
-        'Call to deprecated function _instance_key',
-        'Call to deprecated function _sa_session_id',
-        'Call to deprecated function _entity_name')
-    @testing.resolve_artifact_names
-    def test_legacy_accessors(self):
-        u1 = User(name='u1')
-        assert not hasattr(u1, '_instance_key')
-        assert not hasattr(u1, '_sa_session_id')
-        assert not hasattr(u1, '_entity_name')
-
-        mapper(User, users)
-        u1 = User(name='u2')
-        assert not hasattr(u1, '_instance_key')
-        assert not hasattr(u1, '_sa_session_id')
-        assert u1._entity_name is None
-
-        sess = create_session()
-        sess.save(u1)
-        assert not hasattr(u1, '_instance_key')
-        eq_(u1._sa_session_id, sess.hash_key)
-        assert u1._entity_name is None
-
-        sess.flush()
-        eq_(u1._instance_key,
-            sa.orm.class_mapper(u1).identity_key_from_instance(u1))
-        eq_(u1._sa_session_id, sess.hash_key)
-        assert u1._entity_name is None
-        sess.delete(u1)
-        sess.flush()
 
     @testing.resolve_artifact_names
     def test_bad_cascade(self):
         })
 
         s = create_session()
-        u = s.get(User, 7)
+        u = s.query(User).get(7)
         eq_(u._name, 'jack')
         eq_(u._id,7)
         u2 = s.query(User).filter_by(user_name='jack').one()
                 methods.append('init_failed')
                 return sa.orm.EXT_CONTINUE
 
-            def load(self, query, *args, **kwargs):
-                methods.append('load')
-                return sa.orm.EXT_CONTINUE
-
-            def get(self, query, *args, **kwargs):
-                methods.append('get')
-                return sa.orm.EXT_CONTINUE
-
             def translate_row(self, mapper, context, row):
                 methods.append('translate_row')
                 return sa.orm.EXT_CONTINUE
                 methods.append('create_instance')
                 return sa.orm.EXT_CONTINUE
 
+            def on_reconstitute(self, mapper, instance):
+                methods.append('on_reconstitute')
+                return sa.orm.EXT_CONTINUE
+
             def append_result(self, mapper, selectcontext, row, instance, result, **flags):
                 methods.append('append_result')
                 return sa.orm.EXT_CONTINUE
         u = User(name='u1')
         sess.save(u)
         sess.flush()
-        u = sess.query(User).load(u.id)
+        u = sess.query(User).populate_existing().get(u.id)
         sess.clear()
         u = sess.query(User).get(u.id)
         u.name = 'u1 changed'
         sess.flush()
         eq_(methods,
             ['instrument_class', 'init_instance', 'before_insert',
-             'after_insert', 'load', 'translate_row', 'populate_instance',
-             'append_result', 'get', 'translate_row', 'create_instance',
-             'populate_instance', 'append_result', 'before_update',
+             'after_insert', 'translate_row', 'populate_instance',
+             'append_result', 'translate_row', 'create_instance',
+             'populate_instance', 'on_reconstitute', 'append_result', 'before_update',
              'after_update', 'before_delete', 'after_delete'])
 
     @testing.resolve_artifact_names
         am = AdminUser(name='au1', email_address='au1@e1')
         sess.save(am)
         sess.flush()
-        am = sess.query(AdminUser).load(am.id)
+        am = sess.query(AdminUser).populate_existing().get(am.id)
         sess.clear()
         am = sess.query(AdminUser).get(am.id)
         am.name = 'au1 changed'
         sess.flush()
         eq_(methods,
             ['instrument_class', 'instrument_class', 'init_instance',
-             'before_insert', 'after_insert', 'load', 'translate_row',
-             'populate_instance', 'append_result', 'get', 'translate_row',
-             'create_instance', 'populate_instance', 'append_result',
+             'before_insert', 'after_insert', 'translate_row',
+             'populate_instance', 'append_result', 'translate_row',
+             'create_instance', 'populate_instance', 'on_reconstitute', 'append_result',
              'before_update', 'after_update', 'before_delete', 'after_delete'])
 
     @testing.resolve_artifact_names
         am = AdminUser(name="au1", email_address="au1@e1")
         sess.save(am)
         sess.flush()
-        am = sess.query(AdminUser).load(am.id)
+        am = sess.query(AdminUser).populate_existing().get(am.id)
         sess.clear()
         am = sess.query(AdminUser).get(am.id)
         am.name = 'au1 changed'
         sess.flush()
         eq_(methods,
             ['instrument_class', 'instrument_class', 'init_instance',
-             'before_insert', 'after_insert', 'load', 'translate_row',
-             'populate_instance', 'append_result', 'get', 'translate_row',
-             'create_instance', 'populate_instance', 'append_result',
+             'before_insert', 'after_insert', 'translate_row',
+             'populate_instance', 'append_result', 'translate_row',
+             'create_instance', 'populate_instance', 'on_reconstitute', 'append_result',
              'before_update', 'after_update', 'before_delete', 'after_delete'])
 
     @testing.resolve_artifact_names
         session.flush()
         session.clear()
 
-        f1 = session.get(Foo, f1.id)
+        f1 = session.query(Foo).get(f1.id)
         eq_(f1.data.data, '12345')
 
         f2 = Foo(data=pickleable.BrokenComparable('abc'))
         session.flush()
         session.clear()
 
-        f2 = session.get(Foo, f2.id)
+        f2 = session.query(Foo).get(f2.id)
         eq_(f2.data.data, 'abc')
 
 

test/orm/naturalpks.py

 
         sess.add(u1)
         sess.flush()
-        assert sess.get(User, 'jack') is u1
+        assert sess.query(User).get('jack') is u1
 
         u1.username = 'ed'
         sess.flush()
 
         def go():
-            assert sess.get(User, 'ed') is u1
+            assert sess.query(User).get('ed') is u1
         self.assert_sql_count(testing.db, go, 0)
 
-        assert sess.get(User, 'jack') is None
+        assert sess.query(User).get('jack') is None
 
         sess.clear()
         u1 = sess.query(User).get('ed')
 
         sess.add(u1)
         sess.flush()
-        assert sess.get(User, 'jack') is u1
+        assert sess.query(User).get('jack') is u1
 
         users.update(values={User.username:'jack'}).execute(username='ed')
 
         self.assertRaises(sa.orm.exc.ObjectDeletedError, getattr, u1, 'username')
 
         sess.clear()
-        assert sess.get(User, 'jack') is None
-        assert sess.get(User, 'ed').fullname == 'jack'
+        assert sess.query(User).get('jack') is None
+        assert sess.query(User).get('ed').fullname == 'jack'
 
     @testing.fails_on('mysql')
     @testing.fails_on('sqlite')
         sess.add(u1)
         sess.flush()
 
-        assert sess.get(Address, 'jack1') is u1.addresses[0]
+        assert sess.query(Address).get('jack1') is u1.addresses[0]
 
         u1.username = 'ed'
         sess.flush()
         sess.clear()
         self.assertEquals([Address(username='ed'), Address(username='ed')], sess.query(Address).all())
 
-        u1 = sess.get(User, 'ed')
+        u1 = sess.query(User).get('ed')
         u1.username = 'jack'
         def go():
             sess.flush()
         else:
             self.assert_sql_count(testing.db, go, 1) # test passive_updates=True; update user
         sess.clear()
-        assert User(username='jack', addresses=[Address(username='jack'), Address(username='jack')]) == sess.get(User, 'jack')
+        assert User(username='jack', addresses=[Address(username='jack'), Address(username='jack')]) == sess.query(User).get('jack')
 
-        u1 = sess.get(User, 'jack')
+        u1 = sess.query(User).get('jack')
         u1.addresses = []
         u1.username = 'fred'
         sess.flush()
         sess.clear()
-        assert sess.get(Address, 'jack1').username is None
-        u1 = sess.get(User, 'fred')
+        assert sess.query(Address).get('jack1').username is None
+        u1 = sess.query(User).get('fred')
         self.assertEquals(User(username='fred', fullname='jack'), u1)
 
     @testing.fails_on('sqlite')
         sess.clear()
         self.assertEquals([Address(username='ed'), Address(username='ed')], sess.query(Address).all())
 
-        u1 = sess.get(User, 'ed')
+        u1 = sess.query(User).get('ed')
         assert len(u1.addresses) == 2    # load addresses
         u1.username = 'fred'
         print "--------------------------------"
 
         self.assertEquals(sa.select([addresses.c.username]).execute().fetchall(), [('jack',), ('jack',)])
 
-        assert sess.get(Address, a1.id) is u1.addresses[0]
+        assert sess.query(Address).get(a1.id) is u1.addresses[0]
 
         u1.username = 'ed'
         sess.flush()
         sess.clear()
         self.assertEquals([Address(username='ed'), Address(username='ed')], sess.query(Address).all())
 
-        u1 = sess.get(User, u1.id)
+        u1 = sess.query(User).get(u1.id)
         u1.username = 'jack'
         def go():
             sess.flush()
         else:
             self.assert_sql_count(testing.db, go, 1) # test passive_updates=True; update user
         sess.clear()
-        assert User(username='jack', addresses=[Address(username='jack'), Address(username='jack')]) == sess.get(User, u1.id)
+        assert User(username='jack', addresses=[Address(username='jack'), Address(username='jack')]) == sess.query(User).get(u1.id)
         sess.clear()
 
-        u1 = sess.get(User, u1.id)
+        u1 = sess.query(User).get(u1.id)
         u1.addresses = []
         u1.username = 'fred'
         sess.flush()
         sess.clear()
-        a1 = sess.get(Address, a1.id)
+        a1 = sess.query(Address).get(a1.id)
         self.assertEquals(a1.username, None)
 
         self.assertEquals(sa.select([addresses.c.username]).execute().fetchall(), [(None,), (None,)])
 
-        u1 = sess.get(User, u1.id)
+        u1 = sess.query(User).get(u1.id)
         self.assertEquals(User(username='fred', fullname='jack'), u1)
 
 

test/orm/query.py

         q = s.query(User).join('addresses').filter(Address.user_id==8)
         self.assertRaises(sa_exc.InvalidRequestError, q.get, 7)
         self.assertRaises(sa_exc.InvalidRequestError, s.query(User).filter(User.id==7).get, 19)
-        self.assertRaises(sa_exc.InvalidRequestError, s.query(User).filter(User.id==7).load, 19)
 
     def test_unique_param_names(self):
         class SomeUser(object):
     def test_load(self):
         s = create_session()
 
-        try:
-            assert s.query(User).load(19) is None
-            assert False
-        except sa_exc.InvalidRequestError:
-            assert True
+        assert s.query(User).populate_existing().get(19) is None
 
-        u = s.query(User).load(7)
-        u2 = s.query(User).load(7)
+        u = s.query(User).populate_existing().get(7)
+        u2 = s.query(User).populate_existing().get(7)
         assert u is u2
         s.clear()
-        u2 = s.query(User).load(7)
+        u2 = s.query(User).populate_existing().get(7)
         assert u is not u2
 
         u2.name = 'some name'
         assert u2 in s.dirty
         assert a in u2.addresses
 
-        s.query(User).load(7)
+        s.query(User).populate_existing().get(7)
         assert u2 not in s.dirty
         assert u2.name =='jack'
         assert a not in u2.addresses
         
         eq_(sess.query(User).order_by(User.id).all(), [jack,jane])
     
+    @testing.fails_on('mysql')
     @testing.resolve_artifact_names
     def test_delete_fallback(self):
         sess = create_session(bind=testing.db, autocommit=False)

test/orm/session.py

     # TODO: expand with message body assertions.
 
     _class_methods = set((
-        'connection', 'execute', 'get', 'get_bind', 'load', 'scalar'))
+        'connection', 'execute', 'get_bind', 'scalar'))
 
     def _public_session_methods(self):
         Session = sa.orm.session.Session
 
         raises_('execute', 'SELECT 1', mapper=user_arg)
 
-        raises_('get', user_arg, 1)
-
         raises_('get_bind', mapper=user_arg)
 
-        raises_('load', user_arg, 1)
-
         raises_('scalar', 'SELECT 1', mapper=user_arg)
 
         eq_(watchdog, self._class_methods,

test/orm/transaction.py

 
     def test_attrs_on_rollback(self):
         sess = self.session()
-        u1 = sess.get(User, 7)
+        u1 = sess.query(User).get(7)
         u1.name = 'ed'
         sess.rollback()
         self.assertEquals(u1.name, 'jack')
 
     def test_commit_persistent(self):
         sess = self.session()
-        u1 = sess.get(User, 7)
+        u1 = sess.query(User).get(7)
         u1.name = 'ed'
         sess.flush()
         sess.commit()
 
     def test_concurrent_commit_persistent(self):
         s1 = self.session()
-        u1 = s1.get(User, 7)
+        u1 = s1.query(User).get(7)
         u1.name = 'ed'
         s1.commit()
 
         s2 = self.session()
-        u2 = s2.get(User, 7)
+        u2 = s2.query(User).get(7)
         assert u2.name == 'ed'
         u2.name = 'will'
         s2.commit()

test/orm/unitofwork.py

         self.assertRaises(sa.orm.exc.ConcurrentModificationError, s1.query(Foo).with_lockmode('read').get, f1s1.id)
 
         # reload it
-        s1.query(Foo).load(f1s1.id)
+        s1.query(Foo).populate_existing().get(f1s1.id)
         # now assert version OK
         s1.query(Foo).with_lockmode('read').get(f1s1.id)
 
         session.commit()
         session.clear()
 
-        f1 = session.get(Foo, f1.id)
+        f1 = session.query(Foo).get(f1.id)
         f1.val = u'hi'
         self.sql_count_(0, session.commit)
 
         session.flush()
         session.clear()
 
-        u2 = session.get(User, u2.id)
+        u2 = session.query(User).get(u2.id)
         eq_(len(u2.addresses), 1)
 
     @testing.resolve_artifact_names
         session.flush()
         session.clear()
 
-        u2 = session.get(User, u2.id)
+        u2 = session.query(User).get(u2.id)
         eq_(len(u2.addresses), 1)
 
     @testing.resolve_artifact_names
         session.flush()
 
         # assert the first one retreives the same from the identity map
-        nu = session.get(m, u.id)
+        nu = session.query(m).get(u.id)
         assert u is nu
 
         # clear out the identity map, so next get forces a SELECT
         session.clear()
 
         # check it again, identity should be different but ids the same
-        nu = session.get(m, u.id)
+        nu = session.query(m).get(u.id)
         assert u is not nu and u.id == nu.id and nu.name == 'savetester'
 
         # change first users name and save
 
         id = m.primary_key_from_instance(u)
 
-        u = session.get(User, id)
+        u = session.query(User).get(id)
         assert u.name == 'multitester'
 
         user_rows = users.select(users.c.id.in_([u.foo_id])).execute().fetchall()
         eq_(address_rows[0].values(), [u.id, u.foo_id, 'lala@hey.com'])
 
         session.clear()
-        u = session.get(User, id)
+        u = session.query(User).get(id)
         assert u.name == 'imnew'
 
     @testing.resolve_artifact_names
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.