def init(self, *args, **kwargs):
nohist = kwargs.pop('_mapper_nohistory', False)
session = kwargs.pop('_sa_session', objectstore.get_session())
+ if not nohist:
+ # register new with the correct session, before the object's
+ # constructor is called, since further assignments within the
+ # constructor would otherwise bind it to whatever get_session() is.
+ session.register_new(self)
if oldinit is not None:
try:
oldinit(self, *args, **kwargs)
except TypeError, msg:
# re-raise with the offending class name added to help in debugging
raise TypeError, '%s.%s' %(self.__class__.__name__, msg)
- if not nohist:
- session.register_new(self)
- self.class_.__init__ = init
+ # override oldinit, insuring that its not already one of our
+ # own modified inits
+ if oldinit is None or not hasattr(oldinit, '_sa_mapper_init'):
+ init._sa_mapper_init = True
+ self.class_.__init__ = init
mapper_registry[self.class_] = self
self.class_.c = self.c
mapper.__dict__.update(self.__dict__)
mapper.props = self.props.copy()
return mapper
-
+
+ def using(self, session):
+ """returns a proxying object to this mapper, which will execute methods on the mapper
+ within the context of the given session. The session is placed as the "current" session
+ via the push_session/pop_session methods in the objectstore module."""
+ mapper = self
+ class Proxy(object):
+ def __getattr__(self, key):
+ def callit(*args, **kwargs):
+ objectstore.push_session(session)
+ try:
+ return getattr(mapper, key)(*args, **kwargs)
+ finally:
+ objectstore.pop_session()
+ return callit
+ return Proxy()
+
def options(self, *options):
"""uses this mapper as a prototype for a new mapper with different behavior.
*options is a list of options directives, which include eagerload(), lazyload(), and noload()"""
self.attributes.commit(obj)
def register_new(self, obj):
- self.new.append(obj)
+ if not self.new.contains(obj):
+ self.new.append(obj)
def register_dirty(self, obj):
if not self.dirty.contains(obj):
uow = get_session # deprecated
def push_session(sess):
- old = _sessions.get(thread.get_ident(), None)
+ old = get_session()
sess._previous = old
- _sessions[sess.hash_key] = sess
- _sessions[thread.get_ident()] = sess
+ session_registry.set(sess)
def pop_session():
- sess = _sessions[thread.get_ident()]
+ sess = get_session()
old = sess._previous
sess._previous = None
- _sessions[old.hash_key] = old
- _sessions[thread.get_ident()] = old
+ session_registry.set(old)
return old
def using_session(sess, func):