From: Mike Bayer Date: Thu, 4 Sep 2008 21:26:49 +0000 (+0000) Subject: - Fixed exception throw which would occur when string-based X-Git-Tag: rel_0_5rc1~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f432bd3550443fb27711e463b086deae7c3096df;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed exception throw which would occur when string-based primaryjoin condition was used in conjunction with backref. --- diff --git a/CHANGES b/CHANGES index b395f6edd7..7697e4c009 100644 --- a/CHANGES +++ b/CHANGES @@ -107,7 +107,7 @@ CHANGES by the ORM. - Session.delete() adds the given object to the session if - not already present. This was a regression bug from 0.4 + not already present. This was a regression bug from 0.4. [ticket:1150] - The `echo_uow` flag on `Session` is deprecated, and unit-of-work @@ -116,7 +116,10 @@ CHANGES - declarative - Fixed bug whereby mapper couldn't initialize if a composite primary key referenced another table that was not defined - yet [ticket:1161] + yet. [ticket:1161] + + - Fixed exception throw which would occur when string-based + primaryjoin condition was used in conjunction with backref. - schema - Added "sorted_tables" accessor to MetaData, which returns diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py index 65af2da7ac..85ccea6488 100644 --- a/lib/sqlalchemy/ext/declarative.py +++ b/lib/sqlalchemy/ext/declarative.py @@ -374,6 +374,12 @@ def _deferred_relation(cls, prop): if isinstance(v, basestring): setattr(prop, attr, resolve_arg(v)) + if prop.backref: + for attr in ('primaryjoin', 'secondaryjoin'): + if attr in prop.backref.kwargs and isinstance(prop.backref.kwargs[attr], basestring): + prop.backref.kwargs[attr] = resolve_arg(prop.backref.kwargs[attr]) + + return prop def synonym_for(name, map_column=False): diff --git a/test/ext/declarative.py b/test/ext/declarative.py index 3121f959fe..772dca8e13 100644 --- a/test/ext/declarative.py +++ b/test/ext/declarative.py @@ -4,7 +4,7 @@ from sqlalchemy.ext import declarative as decl from sqlalchemy import exc from testlib import sa, testing from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, ForeignKeyConstraint, asc -from testlib.sa.orm import relation, create_session, class_mapper, eagerload, compile_mappers +from testlib.sa.orm import relation, create_session, class_mapper, eagerload, compile_mappers, backref from testlib.testing import eq_ from orm._base import ComparableEntity @@ -114,7 +114,27 @@ class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults): id = Column(Integer, primary_key=True) rel = relation("User", primaryjoin="User.addresses==Foo.id") self.assertRaisesMessage(exc.InvalidRequestError, "'addresses' is not an instance of ColumnProperty", compile_mappers) - + + def test_string_dependency_resolution_in_backref(self): + class User(Base, ComparableEntity): + __tablename__ = 'users' + id = Column(Integer, primary_key=True) + name = Column(String(50)) + addresses = relation("Address", + primaryjoin="User.id==Address.user_id", + backref="user" + ) + + class Address(Base, ComparableEntity): + __tablename__ = 'addresses' + id = Column(Integer, primary_key=True) + email = Column(String(50)) + user_id = Column(Integer, ForeignKey('users.id')) + + compile_mappers() + eq_(str(User.addresses.property.primaryjoin), str(Address.user.property.primaryjoin)) + + def test_uncompiled_attributes_in_relation(self): class Address(Base, ComparableEntity): __tablename__ = 'addresses'