diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-05-09 16:34:10 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-05-09 16:34:10 +0000 |
commit | 4a6afd469fad170868554bf28578849bf3dfd5dd (patch) | |
tree | b396edc33d567ae19dd244e87137296450467725 /lib/sqlalchemy/orm/dynamic.py | |
parent | 46b7c9dc57a38d5b9e44a4723dad2ad8ec57baca (diff) | |
download | sqlalchemy-4a6afd469fad170868554bf28578849bf3dfd5dd.tar.gz |
r4695 merged to trunk; trunk now becomes 0.5.
0.4 development continues at /sqlalchemy/branches/rel_0_4
Diffstat (limited to 'lib/sqlalchemy/orm/dynamic.py')
-rw-r--r-- | lib/sqlalchemy/orm/dynamic.py | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index 133ad99c8..08e6a57f4 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -1,8 +1,21 @@ -"""'dynamic' collection API. returns Query() objects on the 'read' side, alters -a special AttributeHistory on the 'write' side.""" +# dynamic.py +# Copyright (C) the SQLAlchemy authors and contributors +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php -from sqlalchemy import exceptions, util, logging -from sqlalchemy.orm import attributes, object_session, util as mapperutil, strategies +"""Dynamic collection API. + +Dynamic collections act like Query() objects for read operations and support +basic add/delete mutation. + +""" + +from sqlalchemy import log, util +import sqlalchemy.exceptions as sa_exc + +from sqlalchemy.orm import attributes, object_session, \ + util as mapperutil, strategies from sqlalchemy.orm.query import Query from sqlalchemy.orm.mapper import has_identity, object_mapper @@ -12,16 +25,19 @@ class DynaLoader(strategies.AbstractRelationLoader): self.is_class_level = True self._register_attribute(self.parent.class_, impl_class=DynamicAttributeImpl, target_mapper=self.parent_property.mapper, order_by=self.parent_property.order_by) - def create_row_processor(self, selectcontext, mapper, row): - return (None, None, None) + def create_row_processor(self, selectcontext, path, mapper, row, adapter): + return (None, None) -DynaLoader.logger = logging.class_logger(DynaLoader) +DynaLoader.logger = log.class_logger(DynaLoader) class DynamicAttributeImpl(attributes.AttributeImpl): - def __init__(self, class_, key, typecallable, target_mapper, order_by, **kwargs): - super(DynamicAttributeImpl, self).__init__(class_, key, typecallable, **kwargs) + uses_objects = True + accepts_scalar_loader = False + + def __init__(self, class_, key, typecallable, class_manager, target_mapper, order_by, **kwargs): + super(DynamicAttributeImpl, self).__init__(class_, key, typecallable, class_manager, **kwargs) self.target_mapper = target_mapper - self.order_by=order_by + self.order_by = order_by self.query_class = AppenderQuery def get(self, state, passive=False): @@ -41,20 +57,18 @@ class DynamicAttributeImpl(attributes.AttributeImpl): state.modified = True if self.trackparent and value is not None: - self.sethasparent(value._state, True) - instance = state.obj() + self.sethasparent(attributes.instance_state(value), True) for ext in self.extensions: - ext.append(instance, value, initiator or self) + ext.append(state, value, initiator or self) def fire_remove_event(self, state, value, initiator): state.modified = True if self.trackparent and value is not None: - self.sethasparent(value._state, False) + self.sethasparent(attributes.instance_state(value), False) - instance = state.obj() for ext in self.extensions: - ext.remove(instance, value, initiator or self) + ext.remove(state, value, initiator or self) def set(self, state, value, initiator): if initiator is self: @@ -111,26 +125,32 @@ class AppenderQuery(Query): def session(self): return self.__session() - session = property(session) + session = property(session, lambda s, x:None) def __iter__(self): sess = self.__session() if sess is None: - return iter(self.attr._get_collection_history(self.instance._state, passive=True).added_items) + return iter(self.attr._get_collection_history( + attributes.instance_state(self.instance), + passive=True).added_items) else: return iter(self._clone(sess)) def __getitem__(self, index): sess = self.__session() if sess is None: - return self.attr._get_collection_history(self.instance._state, passive=True).added_items.__getitem__(index) + return self.attr._get_collection_history( + attributes.instance_state(self.instance), + passive=True).added_items.__getitem__(index) else: return self._clone(sess).__getitem__(index) def count(self): sess = self.__session() if sess is None: - return len(self.attr._get_collection_history(self.instance._state, passive=True).added_items) + return len(self.attr._get_collection_history( + attributes.instance_state(self.instance), + passive=True).added_items) else: return self._clone(sess).count() @@ -142,10 +162,7 @@ class AppenderQuery(Query): if sess is None: sess = object_session(instance) if sess is None: - try: - sess = object_mapper(instance).get_session() - except exceptions.InvalidRequestError: - raise exceptions.UnboundExecutionError("Parent instance %s is not bound to a Session, and no contextual session is established; lazy load operation of attribute '%s' cannot proceed" % (mapperutil.instance_str(instance), self.attr.key)) + raise sa_exc.UnboundExecutionError("Parent instance %s is not bound to a Session, and no contextual session is established; lazy load operation of attribute '%s' cannot proceed" % (mapperutil.instance_str(instance), self.attr.key)) q = sess.query(self.attr.target_mapper).with_parent(instance, self.attr.key) if self.attr.order_by: @@ -158,14 +175,14 @@ class AppenderQuery(Query): oldlist = list(self) else: oldlist = [] - self.attr._get_collection_history(self.instance._state, passive=True).replace(oldlist, collection) + self.attr._get_collection_history(attributes.instance_state(self.instance), passive=True).replace(oldlist, collection) return oldlist def append(self, item): - self.attr.append(self.instance._state, item, None) + self.attr.append(attributes.instance_state(self.instance), item, None) def remove(self, item): - self.attr.remove(self.instance._state, item, None) + self.attr.remove(attributes.instance_state(self.instance), item, None) class CollectionHistory(object): |