summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/mapping
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-04-06 23:46:02 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-04-06 23:46:02 +0000
commit2a171e818c2e7cfadcd286399a3740147ff0df45 (patch)
treec91044514931106b35272c56213ea55274a7f7f4 /lib/sqlalchemy/mapping
parent5bda70e770489a09a848d5ac3bfbee0aabd805ab (diff)
downloadsqlalchemy-2a171e818c2e7cfadcd286399a3740147ff0df45.tar.gz
split up Session into Session/LegacySession, added some new constructor args
created AbstractEngine class which provides base for SQLEngine and will also provide base for ConnectionProxy, so SQL binding can be to an engine or specific connection resource ClauseElements get using() method which can take AbstractEngines for execution made more separation between SchemaItems and bound engine
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):