A subset of arguments available to relation() are available here.
"""
- from sqlalchemy.orm.strategies import DynaLoader
+ from sqlalchemy.orm.dynamic import DynaLoader
return PropertyLoader(argument, secondary=secondary, primaryjoin=primaryjoin,
secondaryjoin=secondaryjoin, entity_name=entity_name, foreign_keys=foreign_keys, backref=backref,
def has_parent(class_, instance, key, optimistic=False):
return getattr(class_, key).impl.hasparent(instance._state, optimistic=optimistic)
-def _create_prop(class_, key, uselist, callable_, typecallable, useobject, mutable_scalars, **kwargs):
- if kwargs.pop('dynamic', False):
- from sqlalchemy.orm import dynamic
- return dynamic.DynamicAttributeImpl(class_, key, typecallable, **kwargs)
+def _create_prop(class_, key, uselist, callable_, typecallable, useobject, mutable_scalars, impl_class, **kwargs):
+ if impl_class:
+ return impl_class(class_, key, typecallable, **kwargs)
elif uselist:
return CollectionAttributeImpl(class_, key, callable_, typecallable, **kwargs)
elif useobject:
delattr(class_, attr.impl.key)
delattr(class_, '_class_state')
-def register_attribute(class_, key, uselist, useobject, callable_=None, proxy_property=None, mutable_scalars=False, **kwargs):
+def register_attribute(class_, key, uselist, useobject, callable_=None, proxy_property=None, mutable_scalars=False, impl_class=None, **kwargs):
_init_class_state(class_)
typecallable = kwargs.pop('typecallable', None)
inst = proxy_type(key, proxy_property, comparator)
else:
inst = InstrumentedAttribute(_create_prop(class_, key, uselist, callable_, useobject=useobject,
- typecallable=typecallable, mutable_scalars=mutable_scalars, **kwargs), comparator=comparator)
+ typecallable=typecallable, mutable_scalars=mutable_scalars, impl_class=impl_class, **kwargs), comparator=comparator)
setattr(class_, key, inst)
class_._class_state.attrs[key] = inst
"""'dynamic' collection API. returns Query() objects on the 'read' side, alters
a special AttributeHistory on the 'write' side."""
-from sqlalchemy import exceptions, util
-from sqlalchemy.orm import attributes, object_session, util as mapperutil
+from sqlalchemy import exceptions, util, logging
+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
+
+class DynaLoader(strategies.AbstractRelationLoader):
+ def init_class_attribute(self):
+ 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)
+
+DynaLoader.logger = logging.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)
self.target_mapper = target_mapper
self.order_by=order_by
+ self.query_class = AppenderQuery
def get(self, state, passive=False):
if passive:
return self._get_collection_history(state, passive=True).added_items
else:
- return AppenderQuery(self, state)
+ return self.query_class(self, state)
def get_collection(self, state, user_data=None, passive=True):
if passive:
def do_init(self):
self._all_strategies = {}
- self.strategy = self.create_strategy()
- self._all_strategies[self.strategy.__class__] = self.strategy
- self.strategy.init()
+ self.strategy = self._get_strategy(self.strategy_class)
if self.is_primary():
self.strategy.init_class_attribute()
self.group = kwargs.pop('group', None)
self.deferred = kwargs.pop('deferred', False)
self.comparator = ColumnProperty.ColumnComparator(self)
+ if self.deferred:
+ self.strategy_class = strategies.DeferredColumnLoader
+ else:
+ self.strategy_class = strategies.ColumnLoader
# sanity check
for col in columns:
if not isinstance(col, ColumnElement):
raise ArgumentError('column_property() must be given a ColumnElement as its argument. Try .label() or .as_scalar() for Selectables to fix this.')
- def create_strategy(self):
- if self.deferred:
- return strategies.DeferredColumnLoader(self)
- else:
- return strategies.ColumnLoader(self)
-
def do_init(self):
super(ColumnProperty, self).do_init()
if len(self.columns) > 1 and self.parent.primary_key.issuperset(self.columns):
self.enable_typechecks = enable_typechecks
self.comparator = PropertyLoader.Comparator(self)
self.join_depth = join_depth
- self.strategy_class = strategy_class
+
+ if strategy_class:
+ self.strategy_class = strategy_class
+ elif self.lazy == 'dynamic':
+ from sqlalchemy.orm import dynamic
+ self.strategy_class = dynamic.DynaLoader
+ elif self.lazy is False:
+ self.strategy_class = strategies.EagerLoader
+ elif self.lazy is None:
+ self.strategy_class = strategies.NoLoader
+ else:
+ self.strategy_class = strategies.LazyLoader
+
self._reverse_property = None
if cascade is not None:
return self.cascade.delete_orphan
private = property(private)
- def create_strategy(self):
- if self.strategy_class:
- return self.strategy_class(self)
- elif self.lazy == 'dynamic':
- return strategies.DynaLoader(self)
- elif self.lazy:
- return strategies.LazyLoader(self)
- elif self.lazy is False:
- return strategies.EagerLoader(self)
- elif self.lazy is None:
- return strategies.NoLoader(self)
-
def __str__(self):
return str(self.parent.class_.__name__) + "." + self.key + " (" + str(self.mapper.class_.__name__) + ")"
self.logger.info("register managed %s attribute %s on class %s" % ((self.uselist and "list-holding" or "scalar"), self.key, self.parent.class_.__name__))
sessionlib.register_attribute(class_, self.key, uselist=self.uselist, useobject=True, extension=self.attributeext, cascade=self.cascade, trackparent=True, typecallable=self.parent_property.collection_class, callable_=callable_, comparator=self.parent_property.comparator, **kwargs)
-class DynaLoader(AbstractRelationLoader):
- def init_class_attribute(self):
- self.is_class_level = True
- self._register_attribute(self.parent.class_, dynamic=True, 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)
-
-DynaLoader.logger = logging.class_logger(DynaLoader)
-
class NoLoader(AbstractRelationLoader):
def init_class_attribute(self):
self.is_class_level = True