.. changelog::
:version: 0.8.0b2
+ .. change::
+ :tags: orm, feature
+
+ Allow synonyms to be used when defining primary and secondary
+ joins for relationships.
+
.. change::
:tags: orm, bug
:ticket: 2614
:tags: sql, removed
The long-deprecated and non-functional ``assert_unicode`` flag on
- :func:`.create_engine` as well as :class:`.String` is removed.
\ No newline at end of file
+ :func:`.create_engine` as well as :class:`.String` is removed.
:func:`.relationship` using strings.
"""
-from ...orm.properties import ColumnProperty, RelationshipProperty
+from ...orm.properties import ColumnProperty, RelationshipProperty, \
+ SynonymProperty
from ...schema import _get_table_key
from ...orm import class_mapper
from ... import util
% (self.cls, key))
prop = mp.get_property(key)
- if not isinstance(prop, ColumnProperty):
+ if isinstance(prop, SynonymProperty):
+ key = prop.name
+ elif not isinstance(prop, ColumnProperty):
raise exc.InvalidRequestError(
"Property %r is not an instance of"
" ColumnProperty (i.e. does not correspond"
Session
from sqlalchemy.testing import eq_
from sqlalchemy.util import classproperty
-from sqlalchemy.ext.declarative import declared_attr, AbstractConcreteBase, ConcreteBase
+from sqlalchemy.ext.declarative import declared_attr, AbstractConcreteBase, \
+ ConcreteBase, synonym_for
from sqlalchemy.testing import fixtures
from sqlalchemy.testing.util import gc_collect
"'addresses' is not an instance of "
"ColumnProperty", configure_mappers)
+ def test_string_dependency_resolution_synonym(self):
+ from sqlalchemy.sql import desc
+
+ class User(Base, fixtures.ComparableEntity):
+
+ __tablename__ = 'users'
+ id = Column(Integer, primary_key=True,
+ test_needs_autoincrement=True)
+ name = Column(String(50))
+
+ Base.metadata.create_all()
+ sess = create_session()
+ u1 = User(name='ed')
+ sess.add(u1)
+ sess.flush()
+ sess.expunge_all()
+ eq_(sess.query(User).filter(User.name == 'ed').one(),
+ User(name='ed'))
+
+ class Foo(Base, fixtures.ComparableEntity):
+
+ __tablename__ = 'foo'
+ id = Column(Integer, primary_key=True)
+ _user_id = Column(Integer)
+ rel = relationship('User',
+ uselist=False,
+ foreign_keys=[User.id],
+ primaryjoin='Foo.user_id==User.id')
+
+ @synonym_for('_user_id')
+ @property
+ def user_id(self):
+ return self._user_id
+
+ foo = Foo()
+ foo.rel = u1
+ assert foo.rel == u1
+
def test_string_dependency_resolution_two(self):
class User(Base, fixtures.ComparableEntity):
backref, create_session, configure_mappers, \
clear_mappers, sessionmaker, attributes,\
Session, composite, column_property, foreign,\
- remote
+ remote, synonym
from sqlalchemy.orm.interfaces import ONETOMANY, MANYTOONE, MANYTOMANY
from sqlalchemy.testing import eq_, startswith_, AssertsCompiledSQL, is_
from sqlalchemy.testing import fixtures
)
+class SynonymsAsFKsTest(fixtures.MappedTest):
+ """Syncrules on foreign keys that are also primary"""
+
+ @classmethod
+ def define_tables(cls, metadata):
+ Table("tableA", metadata,
+ Column("id",Integer,primary_key=True,
+ test_needs_autoincrement=True),
+ Column("foo",Integer,),
+ test_needs_fk=True)
+
+ Table("tableB",metadata,
+ Column("id",Integer,primary_key=True,
+ test_needs_autoincrement=True),
+ Column("_a_id", Integer, key='a_id', primary_key=True),
+ test_needs_fk=True)
+
+ @classmethod
+ def setup_classes(cls):
+ class A(cls.Basic):
+ pass
+
+ class B(cls.Basic):
+ @property
+ def a_id(self):
+ return self._a_id
+
+ def test_synonym_fk(self):
+ """test that active history is enabled on a
+ one-to-many/one that has use_get==True"""
+
+ tableB, A, B, tableA = (self.tables.tableB,
+ self.classes.A,
+ self.classes.B,
+ self.tables.tableA)
+
+ mapper(B, tableB, properties={
+ 'a_id': synonym('_a_id', map_column=True)})
+ mapper(A, tableA, properties={
+ 'b': relationship(B, primaryjoin=(tableA.c.id == foreign(B.a_id)),
+ uselist=False)})
+
+ sess = create_session()
+
+ b = B(id=0)
+ a = A(id=0, b=b)
+ sess.add(a)
+ sess.add(b)
+ sess.flush()
+ sess.expunge_all()
+
+ assert a.b == b
+ assert a.id == b.a_id
+ assert a.id == b._a_id
+
+
class FKsAsPksTest(fixtures.MappedTest):
"""Syncrules on foreign keys that are also primary"""