def instances(self, cursor, *mappers, **kwargs):
limit = kwargs.get('limit', None)
offset = kwargs.get('offset', None)
+ session = kwargs.get('session', None)
+ if session is None:
+ session = objectstore.get_session()
populate_existing = kwargs.get('populate_existing', False)
result = util.HistoryArraySet()
row = cursor.fetchone()
if row is None:
break
- self._instance(row, imap, result, populate_existing=populate_existing)
+ self._instance(session, row, imap, result, populate_existing=populate_existing)
i = 0
for m in mappers:
- m._instance(row, imap, otherresults[i])
+ m._instance(session, row, imap, otherresults[i])
i+=1
# store new stuff in the identity map
for value in imap.values():
- objectstore.get_session().register_clean(value)
+ session.register_clean(value)
if mappers:
result = [result] + otherresults
return result
- def get(self, *ident):
+ def get(self, *ident, **kwargs):
"""returns an instance of the object based on the given identifier, or None
if not found. The *ident argument is a
list of primary key columns in the order of the table def's primary key columns."""
key = objectstore.get_id_key(ident, self.class_, self.entity_name)
#print "key: " + repr(key) + " ident: " + repr(ident)
- return self._get(key, ident)
+ return self._get(key, ident, **kwargs)
- def _get(self, key, ident=None, reload=False):
+ def _get(self, key, ident=None, reload=False, session=None):
if not reload and not self.always_refresh:
try:
- return objectstore.get_session()._get(key)
+ if session is None:
+ session = objectstore.get_session()
+ return session._get(key)
except KeyError:
pass
i += 1
try:
statement = self._compile(self._get_clause)
- return self._select_statement(statement, params=params, populate_existing=reload)[0]
+ return self._select_statement(statement, params=params, populate_existing=reload, session=session)[0]
except IndexError:
return None
else:
return self.select_whereclause(whereclause=arg, **kwargs)
- def select_whereclause(self, whereclause=None, params=None, **kwargs):
+ def select_whereclause(self, whereclause=None, params=None, session=None, **kwargs):
statement = self._compile(whereclause, **kwargs)
- return self._select_statement(statement, params=params)
+ return self._select_statement(statement, params=params, session=session)
def count(self, whereclause=None, params=None, **kwargs):
s = self.table.count(whereclause)
def _identity_key(self, row):
return objectstore.get_row_key(row, self.class_, self.pks_by_table[self.table], self.entity_name)
- def _instance(self, row, imap, result = None, populate_existing = False):
+ def _instance(self, session, row, imap, result = None, populate_existing = False):
"""pulls an object instance from the given row and appends it to the given result
list. if the instance already exists in the given identity map, its not added. in
either case, executes all the property loaders on the instance to also process extra
# including modifying any of its related items lists, as its already
# been exposed to being modified by the application.
+ if session is None:
+ session = objectstore.get_session()
+
populate_existing = populate_existing or self.always_refresh
identitykey = self._identity_key(row)
- sess = objectstore.get_session()
- if sess.has_key(identitykey):
- instance = sess._get(identitykey)
+ if session.has_key(identitykey):
+ instance = session._get(identitykey)
isnew = False
- if populate_existing or sess.is_expired(instance, unexpire=True):
+ if populate_existing or session.is_expired(instance, unexpire=True):
if not imap.has_key(identitykey):
imap[identitykey] = instance
for prop in self.props.values():
- prop.execute(instance, row, identitykey, imap, True)
+ prop.execute(session, instance, row, identitykey, imap, True)
if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing) is EXT_PASS:
if result is not None:
result.append_nohistory(instance)
# plugin point
instance = self.extension.create_instance(self, row, imap, self.class_)
if instance is EXT_PASS:
- instance = self.class_(_mapper_nohistory=True, _sa_entity_name=self.entity_name)
+ instance = self.class_(_mapper_nohistory=True, _sa_entity_name=self.entity_name, _sa_session=session)
imap[identitykey] = instance
isnew = True
else:
# call further mapper properties on the row, to pull further
# instances from the row and possibly populate this item.
- if self.extension.populate_instance(self, instance, row, identitykey, imap, isnew) is EXT_PASS:
- self.populate_instance(instance, row, identitykey, imap, isnew)
+ if self.extension.populate_instance(self, session, instance, row, identitykey, imap, isnew) is EXT_PASS:
+ self.populate_instance(session, instance, row, identitykey, imap, isnew)
if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing) is EXT_PASS:
if result is not None:
result.append_nohistory(instance)
newrow[c] = newrow[c.key]
return newrow
- def populate_instance(self, instance, row, identitykey, imap, isnew, frommapper=None):
+ def populate_instance(self, session, instance, row, identitykey, imap, isnew, frommapper=None):
if frommapper is not None:
row = frommapper.translate_row(self, row)
for prop in self.props.values():
- prop.execute(instance, row, identitykey, imap, isnew)
+ prop.execute(session, instance, row, identitykey, imap, isnew)
class MapperProperty(object):
"""an element attached to a Mapper that describes and assists in the loading and saving
of an attribute on an object instance."""
- def execute(self, instance, row, identitykey, imap, isnew):
+ def execute(self, session, instance, row, identitykey, imap, isnew):
"""called when the mapper receives a row. instance is the parent instance
corresponding to the row. """
raise NotImplementedError()
return EXT_PASS
else:
return self.next.append_result(mapper, row, imap, result, instance, isnew, populate_existing)
- def populate_instance(self, mapper, instance, row, identitykey, imap, isnew):
+ def populate_instance(self, mapper, session, instance, row, identitykey, imap, isnew):
"""called right before the mapper, after creating an instance from a row, passes the row
to its MapperProperty objects which are responsible for populating the object's attributes.
If this method returns True, it is assumed that the mapper should do the appending, else
Essentially, this method is used to have a different mapper populate the object:
- def populate_instance(self, mapper, instance, row, identitykey, imap, isnew):
- othermapper.populate_instance(instance, row, identitykey, imap, isnew, frommapper=mapper)
+ def populate_instance(self, mapper, session, instance, row, identitykey, imap, isnew):
+ othermapper.populate_instance(session, instance, row, identitykey, imap, isnew, frommapper=mapper)
return True
"""
if self.next is None:
return EXT_PASS
else:
- return self.next.populate_instance(mapper, instance, row, identitykey, imap, isnew)
+ return self.next.populate_instance(mapper, session, instance, row, identitykey, imap, isnew)
def before_insert(self, mapper, instance):
"""called before an object instance is INSERTed into its table.
if parent._is_primary_mapper():
#print "regiser col on class %s key %s" % (parent.class_.__name__, key)
objectstore.uow().register_attribute(parent.class_, key, uselist = False)
- def execute(self, instance, row, identitykey, imap, isnew):
+ def execute(self, session, instance, row, identitykey, imap, isnew):
if isnew:
#print "POPULATING OBJ", instance.__class__.__name__, "COL", self.columns[0]._label, "WITH DATA", row[self.columns[0]], "ROW IS A", row.__class__.__name__, "COL ID", id(self.columns[0])
instance.__dict__[self.key] = row[self.columns[0]]
return lazyload
def setup(self, key, statement, **options):
pass
- def execute(self, instance, row, identitykey, imap, isnew):
+ def execute(self, session, instance, row, identitykey, imap, isnew):
if isnew:
if not self.is_primary():
objectstore.global_attributes.create_history(instance, self.key, False, callable_=self.setup_loader(instance))
self._synchronize(obj, child, None, True)
uowcommit.register_object(child, isdelete=self.private)
- def execute(self, instance, row, identitykey, imap, isnew):
+ def execute(self, session, instance, row, identitykey, imap, isnew):
if self.is_primary():
return
#print "PLAIN PROPLOADER EXEC NON-PRIAMRY", repr(id(self)), repr(self.mapper.class_), self.key
def lazyload():
params = {}
allparams = True
+ session = objectstore.get_session(instance)
#print "setting up loader, lazywhere", str(self.lazywhere)
for col, bind in self.lazybinds.iteritems():
params[bind.key] = self.parent._getattrbycolumn(instance, col)
ident = []
for primary_key in self.mapper.pks_by_table[self.mapper.table]:
ident.append(params[primary_key._label])
- return self.mapper.get(*ident)
+ return self.mapper.get(session=session, *ident)
elif self.order_by is not False:
order_by = self.order_by
elif self.secondary is not None and self.secondary.default_order_by() is not None:
order_by = self.secondary.default_order_by()
else:
order_by = False
- result = self.mapper.select_whereclause(self.lazywhere, order_by=order_by, params=params)
+ result = self.mapper.select_whereclause(self.lazywhere, order_by=order_by, params=params, session=session)
else:
result = []
if self.uselist:
return None
return lazyload
- def execute(self, instance, row, identitykey, imap, isnew):
+ def execute(self, session, instance, row, identitykey, imap, isnew):
if isnew:
# new object instance being loaded from a result row
if not self.is_primary():
value.setup(key, statement, eagertable=self.eagertarget)
- def execute(self, instance, row, identitykey, imap, isnew):
+ def execute(self, session, instance, row, identitykey, imap, isnew):
"""receive a row. tell our mapper to look for a new object instance in the row, and attach
it to a list on the parent instance."""
if not self.uselist:
if isnew:
- h.setattr_clean(self._instance(row, imap))
+ h.setattr_clean(self._instance(session, row, imap))
else:
# call _instance on the row, even though the object has been created,
# so that we further descend into properties
- self._instance(row, imap)
+ self._instance(session, row, imap)
return
elif isnew:
else:
result_list = getattr(instance, self.key)
- self._instance(row, imap, result_list)
+ self._instance(session, row, imap, result_list)
def _create_decorator_row(self):
class DecoratorDict(object):
map[parent.name] = c
return DecoratorDict
- def _instance(self, row, imap, result_list=None):
+ def _instance(self, session, row, imap, result_list=None):
"""gets an instance from a row, via this EagerLoader's mapper."""
# since the EagerLoader makes an Alias of its mapper's table,
# we translate the actual result columns back to what they
# (which is what mappers use) as well as its "label" (which might be what
# user-defined code is using)
row = self._row_decorator(row)
- return self.mapper._instance(row, imap, result_list)
+ return self.mapper._instance(session, row, imap, result_list)
class GenericOption(MapperOption):
"""a mapper option that can handle dotted property names,