* post_update - this indicates that the relationship should be handled by a second UPDATE statement after an INSERT, or before a DELETE. using this flag essentially means the relationship will not incur any "dependency" between parent and child item, as the particular foreign key relationship between them is handled by a second statement. use this flag when a particular mapping arrangement will incur two rows that are dependent on each other, such as a table that has a one-to-many relationship to a set of child rows, and also has a column that references a single child row within that list (i.e. both tables contain a foreign key to each other). If a flush() operation returns an error that a "cyclical dependency" was detected, this is a cue that you might want to use post_update.
* viewonly=(True|False) - when set to True, the relation is used only for loading objects within the relationship, and has no effect on the unit-of-work flush process. relations with viewonly can specify any kind of join conditions to provide additional views of related objects onto a parent object.
* collection_class = None - a class or function that returns a new list-holding object. will be used in place of a plain list for storing elements.
+* passive_deletes = False - if False, child instances will be loaded from the database into the current session when a parent instance is deleted so that delete cascade can be processed on those child instances, even if they were not loaded already. When set to True, lazy loaders will not be fired off in order to process a "delete" cascade, which is appropriate if "ON DELETE" rules have been set up on the database tables themselves.
### Controlling Ordering {@name=orderby}
class PropertyLoader(StrategizedProperty):
"""describes an object property that holds a single item or list of items that correspond
to a related database table."""
- def __init__(self, argument, secondary, primaryjoin, secondaryjoin, foreignkey=None, uselist=None, private=False, association=None, order_by=False, attributeext=None, backref=None, is_backref=False, post_update=False, cascade=None, viewonly=False, lazy=True, collection_class=None):
+ def __init__(self, argument, secondary, primaryjoin, secondaryjoin, foreignkey=None, uselist=None, private=False, association=None, order_by=False, attributeext=None, backref=None, is_backref=False, post_update=False, cascade=None, viewonly=False, lazy=True, collection_class=None, passive_deletes=False):
self.uselist = uselist
self.argument = argument
self.secondary = secondary
self.lazy = lazy
self.foreignkey = util.to_set(foreignkey)
self.collection_class = collection_class
-
+ self.passive_deletes = passive_deletes
+
if cascade is not None:
self.cascade = mapperutil.CascadeOptions(cascade)
else:
def cascade_iterator(self, type, object, recursive):
if not type in self.cascade:
return
- childlist = sessionlib.attribute_manager.get_history(object, self.key, passive=True)
+ passive = type != 'delete' or self.passive_deletes
+ childlist = sessionlib.attribute_manager.get_history(object, self.key, passive=passive)
if childlist is None:
return
mapper = self.mapper.primary_mapper()
return
mapper = self.mapper.primary_mapper()
- for c in sessionlib.attribute_manager.get_as_list(object, self.key, passive=True):
+ passive = type != 'delete' or self.passive_deletes
+ for c in sessionlib.attribute_manager.get_as_list(object, self.key, passive=passive):
if c is not None and c not in recursive:
recursive.add(c)
callable_(c, mapper.entity_name)
proxies = {}
+ERROR_ON_RETURN = False
+
def manage(module, **params):
"""given a DBAPI2 module and pool management parameters, returns a proxy for the module
that will automatically pool connections, creating new connection pools for each
# damn mysql -- (todo look for NotSupportedError)
pass
if self._connection_record is not None:
+ global ERROR_ON_RETURN
+ if ERROR_ON_RETURN:
+ ERROR_ON_RETURN=False
+ raise "hi"
+
if self.__pool.echo:
self.__pool.log("Connection %s being returned to pool" % repr(self.connection))
self.__pool.return_conn(self)
pool_size=5 - the number of threads in which to maintain connections at once."""
def __init__(self, creator, pool_size=5, **params):
+ params['use_threadlocal'] = True
Pool.__init__(self, creator, **params)
self._conns = {}
self.size = pool_size