From: Mike Bayer Date: Tue, 21 Oct 2008 16:17:24 +0000 (+0000) Subject: - added NoReferencedColumnError, common base class of NoReferenceError X-Git-Tag: rel_0_5rc3~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e17b7f4bc948be522169dd54c611f1c903438543;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - added NoReferencedColumnError, common base class of NoReferenceError - relation() won't hide unrelated ForeignKey errors inside of the "please specify primaryjoin" message when determining join condition. --- diff --git a/CHANGES b/CHANGES index 12e14b7f13..afc5209db0 100644 --- a/CHANGES +++ b/CHANGES @@ -17,7 +17,11 @@ CHANGES - Improved weakref identity map memory management to no longer require mutexing, resurrects garbage collected instance on a lazy basis for an InstanceState with pending changes. - + + - relation() won't hide unrelated ForeignKey errors inside of + the "please specify primaryjoin" message when determining + join condition. + - sql - Further simplified SELECT compilation and its relationship to result row processing. diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index 96c2e4177a..f82c632f67 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -63,9 +63,15 @@ class InvalidRequestError(SQLAlchemyError): class NoSuchColumnError(KeyError, InvalidRequestError): """A nonexistent column is requested from a ``RowProxy``.""" -class NoReferencedTableError(InvalidRequestError): +class NoReferenceError(InvalidRequestError): + """Raised by ``ForeignKey`` to indicate a reference cannot be resolved.""" + +class NoReferencedTableError(NoReferenceError): """Raised by ``ForeignKey`` when the referred ``Table`` cannot be located.""" +class NoReferencedColumnError(NoReferenceError): + """Raised by ``ForeignKey`` when the referred ``Column`` cannot be located.""" + class NoSuchTableError(InvalidRequestError): """Table does not exist or is not visible to a connection.""" diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 40bca8a119..473c71f7ed 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -13,7 +13,7 @@ attributes. from sqlalchemy import sql, util, log import sqlalchemy.exceptions as sa_exc -from sqlalchemy.sql.util import ClauseAdapter, criterion_as_pairs +from sqlalchemy.sql.util import ClauseAdapter, criterion_as_pairs, join_condition from sqlalchemy.sql import operators, expression from sqlalchemy.orm import ( attributes, dependency, mapper, object_mapper, strategies, @@ -581,19 +581,19 @@ class PropertyLoader(StrategizedProperty): # found will try the more general mapped table, which in the case of inheritance # is a join. try: - return sql.join(mapper.local_table, table) + return join_condition(mapper.local_table, table) except sa_exc.ArgumentError, e: - return sql.join(mapper.mapped_table, table) + return join_condition(mapper.mapped_table, table) try: if self.secondary is not None: if self.secondaryjoin is None: - self.secondaryjoin = _search_for_join(self.mapper, self.secondary).onclause + self.secondaryjoin = _search_for_join(self.mapper, self.secondary) if self.primaryjoin is None: - self.primaryjoin = _search_for_join(self.parent, self.secondary).onclause + self.primaryjoin = _search_for_join(self.parent, self.secondary) else: if self.primaryjoin is None: - self.primaryjoin = _search_for_join(self.parent, self.target).onclause + self.primaryjoin = _search_for_join(self.parent, self.target) except sa_exc.ArgumentError, e: raise sa_exc.ArgumentError("Could not determine join condition between " "parent/child tables on relation %s. " diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 334c277b45..567b1d43ae 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -856,7 +856,7 @@ class ForeignKey(SchemaItem): else: self._column = table.c[colname] except KeyError, e: - raise exc.ArgumentError( + raise exc.NoReferencedColumnError( "Could not create ForeignKey '%s' on table '%s': " "table '%s' has no column named '%s'" % ( self._colspec, parenttable.name, table.name, str(e))) diff --git a/test/orm/relationships.py b/test/orm/relationships.py index 037df35fb2..2989fcda90 100644 --- a/test/orm/relationships.py +++ b/test/orm/relationships.py @@ -1,8 +1,8 @@ import testenv; testenv.configure_for_tests() import datetime from testlib import sa, testing -from testlib.sa import Table, Column, Integer, String, ForeignKey -from testlib.sa.orm import mapper, relation, backref, create_session +from testlib.sa import Table, Column, Integer, String, ForeignKey, MetaData +from testlib.sa.orm import mapper, relation, backref, create_session, compile_mappers, clear_mappers from testlib.testing import eq_, startswith_ from orm import _base @@ -649,6 +649,60 @@ class RelationTest6(_base.MappedTest): sess.query(TagInstance).order_by(TagInstance.data).all(), [TagInstance(data='iplc_case'), TagInstance(data='not_iplc_case')] ) + + +class JoinConditionErrorTest(testing.TestBase): + def test_fk_error_raised(self): + m = MetaData() + t1 = Table('t1', m, + Column('id', Integer, primary_key=True), + Column('foo_id', Integer, ForeignKey('t2.nonexistent_id')), + ) + t2 = Table('t2', m, + Column('id', Integer, primary_key=True), + ) + + t3 = Table('t3', m, + Column('id', Integer, primary_key=True), + Column('t1id', Integer, ForeignKey('t1.id')) + ) + + class C1(object): + pass + class C2(object): + pass + + mapper(C1, t1, properties={'c2':relation(C2)}) + mapper(C2, t3) + + self.assertRaises(sa.exc.NoReferencedColumnError, compile_mappers) + + def test_join_error_raised(self): + m = MetaData() + t1 = Table('t1', m, + Column('id', Integer, primary_key=True), + ) + t2 = Table('t2', m, + Column('id', Integer, primary_key=True), + ) + + t3 = Table('t3', m, + Column('id', Integer, primary_key=True), + Column('t1id', Integer) + ) + + class C1(object): + pass + class C2(object): + pass + + mapper(C1, t1, properties={'c2':relation(C2)}) + mapper(C2, t3) + + self.assertRaises(sa.exc.ArgumentError, compile_mappers) + + def tearDown(self): + clear_mappers() class TypeMatchTest(_base.MappedTest): """test errors raised when trying to add items whose type is not handled by a relation"""