"many-to-one/one-to-one relationships and/or "
"uselist=False." % self.parent_property)
strategies._register_attribute(
- self,
+ self.parent_property,
mapper,
useobject=True,
- uselist=True,
impl_class=DynamicAttributeImpl,
target_mapper=self.parent_property.mapper,
order_by=self.parent_property.order_by,
query_class=self.parent_property.query_class,
- backref=self.parent_property.back_populates,
)
def _register_attribute(
- strategy, mapper, useobject,
+ prop, mapper, useobject,
compare_function=None,
typecallable=None,
- uselist=False,
callable_=None,
proxy_property=None,
active_history=False,
**kw
):
- prop = strategy.parent_property
-
attribute_ext = list(util.to_list(prop.extension, default=[]))
listen_hooks = []
+ uselist = useobject and prop.uselist
+
if useobject and prop.single_parent:
listen_hooks.append(single_parent_validator)
# need to assemble backref listeners
# after the singleparentvalidator, mapper validator
- backref = kw.pop('backref', None)
- if backref:
- listen_hooks.append(
- lambda desc, prop: attributes.backref_listeners(
- desc,
- backref,
- uselist
+ if useobject:
+ backref = prop.back_populates
+ if backref:
+ listen_hooks.append(
+ lambda desc, prop: attributes.backref_listeners(
+ desc,
+ backref,
+ uselist
+ )
)
- )
# a single MapperProperty is shared down a class inheritance
# hierarchy, so we set up attribute instrumentation and backref event
mapper.version_id_col in set(self.columns)
_register_attribute(
- self, mapper, useobject=False,
+ self.parent_property, mapper, useobject=False,
compare_function=coltype.compare_values,
active_history=active_history
)
self.is_class_level = True
_register_attribute(
- self, mapper, useobject=False,
+ self.parent_property, mapper, useobject=False,
compare_function=self.columns[0].type.compare_values,
callable_=self._load_for_state,
expire_missing=False
self.is_class_level = True
_register_attribute(
- self, mapper,
+ self.parent_property, mapper,
useobject=True,
- uselist=self.parent_property.uselist,
typecallable=self.parent_property.collection_class,
)
# in that case. otherwise we don't need the
# "old" value during backref operations.
_register_attribute(
- self,
+ self.parent_property,
mapper,
useobject=True,
callable_=self._load_for_state,
- uselist=self.parent_property.uselist,
- backref=self.parent_property.back_populates,
typecallable=self.parent_property.collection_class,
active_history=active_history
)
Session, composite, column_property, foreign,\
remote, synonym, joinedload, subqueryload
from sqlalchemy.orm.interfaces import ONETOMANY, MANYTOONE
-from sqlalchemy.testing import eq_, startswith_, AssertsCompiledSQL, is_
+from sqlalchemy.testing import eq_, startswith_, AssertsCompiledSQL, is_, in_
from sqlalchemy.testing import fixtures
from test.orm import _fixtures
from sqlalchemy import exc
configure_mappers)
+
+class NoLoadBackPopulates(_fixtures.FixtureTest):
+
+ """test the noload stratgegy which unlike others doesn't use
+ lazyloader to set up instrumentation"""
+
+ def test_o2m(self):
+ users, Address, addresses, User = (self.tables.users,
+ self.classes.Address,
+ self.tables.addresses,
+ self.classes.User)
+
+ mapper(User, users, properties={
+ 'addresses': relationship(
+ Address, back_populates='user', lazy="noload")
+ })
+
+ mapper(Address, addresses, properties={
+ 'user': relationship(User)
+ })
+
+ u1 = User()
+ a1 = Address()
+ u1.addresses.append(a1)
+ is_(a1.user, u1)
+
+ def test_m2o(self):
+ users, Address, addresses, User = (self.tables.users,
+ self.classes.Address,
+ self.tables.addresses,
+ self.classes.User)
+
+ mapper(User, users, properties={
+ 'addresses': relationship(
+ Address)
+ })
+
+ mapper(Address, addresses, properties={
+ 'user': relationship(
+ User, back_populates='addresses', lazy="noload")
+ })
+
+ u1 = User()
+ a1 = Address()
+ a1.user = u1
+ in_(a1, u1.addresses)
+
+
class JoinConditionErrorTest(fixtures.TestBase):
def test_clauseelement_pj(self):