summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/dynamic.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-05-09 16:34:10 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-05-09 16:34:10 +0000
commit4a6afd469fad170868554bf28578849bf3dfd5dd (patch)
treeb396edc33d567ae19dd244e87137296450467725 /lib/sqlalchemy/orm/dynamic.py
parent46b7c9dc57a38d5b9e44a4723dad2ad8ec57baca (diff)
downloadsqlalchemy-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.py71
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):