summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/mapping
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/mapping')
-rw-r--r--lib/sqlalchemy/mapping/objectstore.py209
-rw-r--r--lib/sqlalchemy/mapping/query.py5
2 files changed, 116 insertions, 98 deletions
diff --git a/lib/sqlalchemy/mapping/objectstore.py b/lib/sqlalchemy/mapping/objectstore.py
index 1491d39ac..faf5ddbd6 100644
--- a/lib/sqlalchemy/mapping/objectstore.py
+++ b/lib/sqlalchemy/mapping/objectstore.py
@@ -17,7 +17,7 @@ import sqlalchemy
class Session(object):
"""Maintains a UnitOfWork instance, including transaction state."""
- def __init__(self, nest_on=None, hash_key=None):
+ def __init__(self, hash_key=None, new_imap=True, import_session=None):
"""Initialize the objectstore with a UnitOfWork registry. If called
with no arguments, creates a single UnitOfWork for all operations.
@@ -26,31 +26,23 @@ class Session(object):
hash_key - the hash_key used to identify objects against this session, which
defaults to the id of the Session instance.
"""
- self.uow = unitofwork.UnitOfWork()
- self.parent_uow = None
- self.begin_count = 0
- self.nest_on = util.to_list(nest_on)
- self.__pushed_count = 0
+ if import_session is not None:
+ self.uow = unitofwork.UnitOfWork(identity_map=import_session.uow.identity_map)
+ elif new_imap is False:
+ self.uow = unitofwork.UnitOfWork(identity_map=objectstore.get_session().uow.identity_map)
+ else:
+ self.uow = unitofwork.UnitOfWork()
+
+ self.binds = {}
if hash_key is None:
self.hash_key = id(self)
else:
self.hash_key = hash_key
_sessions[self.hash_key] = self
- def was_pushed(self):
- if self.nest_on is None:
- return
- self.__pushed_count += 1
- if self.__pushed_count == 1:
- for n in self.nest_on:
- n.push_session()
- def was_popped(self):
- if self.nest_on is None or self.__pushed_count == 0:
- return
- self.__pushed_count -= 1
- if self.__pushed_count == 0:
- for n in self.nest_on:
- n.pop_session()
+ def bind_table(self, table, bindto):
+ self.binds[table] = bindto
+
def get_id_key(ident, class_, entity_name=None):
"""returns an identity-map key for use in storing/retrieving an item from the identity
map, given a tuple of the object's primary key values.
@@ -81,79 +73,12 @@ class Session(object):
"""
return (class_, tuple([row[column] for column in primary_key]), entity_name)
get_row_key = staticmethod(get_row_key)
-
- class SessionTrans(object):
- """returned by Session.begin(), denotes a transactionalized UnitOfWork instance.
- call commit() on this to commit the transaction."""
- def __init__(self, parent, uow, isactive):
- self.__parent = parent
- self.__isactive = isactive
- self.__uow = uow
- isactive = property(lambda s:s.__isactive, doc="True if this SessionTrans is the 'active' transaction marker, else its a no-op.")
- parent = property(lambda s:s.__parent, doc="returns the parent Session of this SessionTrans object.")
- uow = property(lambda s:s.__uow, doc="returns the parent UnitOfWork corresponding to this transaction.")
- def begin(self):
- """calls begin() on the underlying Session object, returning a new no-op SessionTrans object."""
- if self.parent.uow is not self.uow:
- raise InvalidRequestError("This SessionTrans is no longer valid")
- return self.parent.begin()
- def commit(self):
- """commits the transaction noted by this SessionTrans object."""
- self.__parent._trans_commit(self)
- self.__isactive = False
- def rollback(self):
- """rolls back the current UnitOfWork transaction, in the case that begin()
- has been called. The changes logged since the begin() call are discarded."""
- self.__parent._trans_rollback(self)
- self.__isactive = False
-
- def begin(self):
- """begins a new UnitOfWork transaction and returns a tranasaction-holding
- object. commit() or rollback() should be called on the returned object.
- commit() on the Session will do nothing while a transaction is pending, and further
- calls to begin() will return no-op transactional objects."""
- if self.parent_uow is not None:
- return Session.SessionTrans(self, self.uow, False)
- self.parent_uow = self.uow
- self.uow = unitofwork.UnitOfWork(identity_map = self.uow.identity_map)
- return Session.SessionTrans(self, self.uow, True)
def engines(self, mapper):
return [t.engine for t in mapper.tables]
- def _trans_commit(self, trans):
- if trans.uow is self.uow and trans.isactive:
- try:
- self._commit_uow()
- finally:
- self.uow = self.parent_uow
- self.parent_uow = None
- def _trans_rollback(self, trans):
- if trans.uow is self.uow:
- self.uow = self.parent_uow
- self.parent_uow = None
-
- def _commit_uow(self, *obj):
- self.was_pushed()
- try:
- self.uow.flush(self, *obj)
- finally:
- self.was_popped()
-
- def commit(self, *objects):
- """commits the current UnitOfWork transaction. called with
- no arguments, this is only used
- for "implicit" transactions when there was no begin().
- if individual objects are submitted, then only those objects are committed, and the
- begin/commit cycle is not affected."""
- # if an object list is given, commit just those but dont
- # change begin/commit status
- if len(objects):
- self._commit_uow(*objects)
- self.uow.flush(self, *objects)
- return
- if self.parent_uow is None:
- self._commit_uow()
+ def flush(self, *obj):
+ self.uow.flush(self, *obj)
def refresh(self, *obj):
"""reloads the attributes for the given objects from the database, clears
@@ -221,6 +146,95 @@ class Session(object):
u.register_new(instance)
return instance
+class LegacySession(Session):
+ def __init__(self, nest_on=None, hash_key=None, **kwargs):
+ super(LegacySession, self).__init__(**kwargs)
+ self.parent_uow = None
+ self.begin_count = 0
+ self.nest_on = util.to_list(nest_on)
+ self.__pushed_count = 0
+ def was_pushed(self):
+ if self.nest_on is None:
+ return
+ self.__pushed_count += 1
+ if self.__pushed_count == 1:
+ for n in self.nest_on:
+ n.push_session()
+ def was_popped(self):
+ if self.nest_on is None or self.__pushed_count == 0:
+ return
+ self.__pushed_count -= 1
+ if self.__pushed_count == 0:
+ for n in self.nest_on:
+ n.pop_session()
+ class SessionTrans(object):
+ """returned by Session.begin(), denotes a transactionalized UnitOfWork instance.
+ call commit() on this to commit the transaction."""
+ def __init__(self, parent, uow, isactive):
+ self.__parent = parent
+ self.__isactive = isactive
+ self.__uow = uow
+ isactive = property(lambda s:s.__isactive, doc="True if this SessionTrans is the 'active' transaction marker, else its a no-op.")
+ parent = property(lambda s:s.__parent, doc="returns the parent Session of this SessionTrans object.")
+ uow = property(lambda s:s.__uow, doc="returns the parent UnitOfWork corresponding to this transaction.")
+ def begin(self):
+ """calls begin() on the underlying Session object, returning a new no-op SessionTrans object."""
+ if self.parent.uow is not self.uow:
+ raise InvalidRequestError("This SessionTrans is no longer valid")
+ return self.parent.begin()
+ def commit(self):
+ """commits the transaction noted by this SessionTrans object."""
+ self.__parent._trans_commit(self)
+ self.__isactive = False
+ def rollback(self):
+ """rolls back the current UnitOfWork transaction, in the case that begin()
+ has been called. The changes logged since the begin() call are discarded."""
+ self.__parent._trans_rollback(self)
+ self.__isactive = False
+ def begin(self):
+ """begins a new UnitOfWork transaction and returns a tranasaction-holding
+ object. commit() or rollback() should be called on the returned object.
+ commit() on the Session will do nothing while a transaction is pending, and further
+ calls to begin() will return no-op transactional objects."""
+ if self.parent_uow is not None:
+ return Session.SessionTrans(self, self.uow, False)
+ self.parent_uow = self.uow
+ self.uow = unitofwork.UnitOfWork(identity_map = self.uow.identity_map)
+ return Session.SessionTrans(self, self.uow, True)
+ def commit(self, *objects):
+ """commits the current UnitOfWork transaction. called with
+ no arguments, this is only used
+ for "implicit" transactions when there was no begin().
+ if individual objects are submitted, then only those objects are committed, and the
+ begin/commit cycle is not affected."""
+ # if an object list is given, commit just those but dont
+ # change begin/commit status
+ if len(objects):
+ self._commit_uow(*objects)
+ self.uow.flush(self, *objects)
+ return
+ if self.parent_uow is None:
+ self._commit_uow()
+ def _trans_commit(self, trans):
+ if trans.uow is self.uow and trans.isactive:
+ try:
+ self._commit_uow()
+ finally:
+ self.uow = self.parent_uow
+ self.parent_uow = None
+ def _trans_rollback(self, trans):
+ if trans.uow is self.uow:
+ self.uow = self.parent_uow
+ self.parent_uow = None
+ def _commit_uow(self, *obj):
+ self.was_pushed()
+ try:
+ self.uow.flush(self, *obj)
+ finally:
+ self.was_popped()
+
+Session = LegacySession
+
def get_id_key(ident, class_, entity_name=None):
return Session.get_id_key(ident, class_, entity_name)
@@ -228,19 +242,22 @@ def get_row_key(row, class_, primary_key, entity_name=None):
return Session.get_row_key(row, class_, primary_key, entity_name)
def begin():
- """begins a new UnitOfWork transaction. the next commit will affect only
- objects that are created, modified, or deleted following the begin statement."""
+ """deprecated. use s = Session(new_imap=False)."""
return get_session().begin()
def commit(*obj):
- """commits the current UnitOfWork transaction. if a transaction was begun
- via begin(), commits only those objects that were created, modified, or deleted
- since that begin statement. otherwise commits all objects that have been
+ """deprecated; use flush(*obj)"""
+ get_session().flush(*obj)
+
+def flush(*obj):
+ """flushes the current UnitOfWork transaction. if a transaction was begun
+ via begin(), flushes only those objects that were created, modified, or deleted
+ since that begin statement. otherwise flushes all objects that have been
changed.
-
+
if individual objects are submitted, then only those objects are committed, and the
begin/commit cycle is not affected."""
- get_session().commit(*obj)
+ get_session().flush(*obj)
def clear():
"""removes all current UnitOfWorks and IdentityMaps for this thread and
diff --git a/lib/sqlalchemy/mapping/query.py b/lib/sqlalchemy/mapping/query.py
index 09c2b9b6e..950c2be42 100644
--- a/lib/sqlalchemy/mapping/query.py
+++ b/lib/sqlalchemy/mapping/query.py
@@ -10,6 +10,7 @@ class Query(object):
self.mapper = mapper
self.always_refresh = kwargs.pop('always_refresh', self.mapper.always_refresh)
self.order_by = kwargs.pop('order_by', self.mapper.order_by)
+ self.extension = kwargs.pop('extension', self.mapper.extension)
self._session = kwargs.pop('session', None)
if not hasattr(mapper, '_get_clause'):
_get_clause = sql.and_()
@@ -66,7 +67,7 @@ class Query(object):
e.g. result = usermapper.select_by(user_name = 'fred')
"""
- ret = self.mapper.extension.select_by(self, *args, **params)
+ ret = self.extension.select_by(self, *args, **params)
if ret is not mapper.EXT_PASS:
return ret
return self.select_whereclause(self._by_clause(*args, **params))
@@ -116,7 +117,7 @@ class Query(object):
in this case, the developer must insure that an adequate set of columns exists in the
rowset with which to build new object instances."""
- ret = self.mapper.extension.select(self, arg=arg, **kwargs)
+ ret = self.extension.select(self, arg=arg, **kwargs)
if ret is not mapper.EXT_PASS:
return ret
elif arg is not None and isinstance(arg, sql.Selectable):