diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-05-07 12:52:25 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-05-07 12:52:25 -0400 |
| commit | 4bc2402cc0bc585af1d0e7d59000f73cf20cf452 (patch) | |
| tree | bc753ce330385f31c870ad5ecc4230e899967599 /lib/sqlalchemy | |
| parent | 7adcb1c7443265fc99d05714c964c795f0fe1c13 (diff) | |
| download | sqlalchemy-4bc2402cc0bc585af1d0e7d59000f73cf20cf452.tar.gz | |
- Changed the handling in determination of join
conditions such that foreign key errors are
only considered between the two given tables.
That is, t1.join(t2) will report FK errors
that involve 't1' or 't2', but anything
involving 't3' will be skipped. This affects
join(), as well as ORM relationship and
inherit condition logic. Will keep the more conservative
approach to [ticket:2153] in 0.6.
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/exc.py | 9 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 3 | ||||
| -rw-r--r-- | lib/sqlalchemy/schema.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/util.py | 27 |
4 files changed, 27 insertions, 18 deletions
diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index 99214dfdd..c52924cfb 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -78,9 +78,18 @@ class NoReferenceError(InvalidRequestError): class NoReferencedTableError(NoReferenceError): """Raised by ``ForeignKey`` when the referred ``Table`` cannot be located.""" + def __init__(self, message, tname): + super(NoReferencedTableError, self).__init__(message) + self.table_name = tname + class NoReferencedColumnError(NoReferenceError): """Raised by ``ForeignKey`` when the referred ``Column`` cannot be located.""" + def __init__(self, message, tname, cname): + super(NoReferencedColumnError, self).__init__(message) + self.table_name = tname + self.column_name = cname + class NoSuchTableError(InvalidRequestError): """Table does not exist or is not visible to a connection.""" diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 03f3e90db..53f8af0b4 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -470,8 +470,7 @@ class Mapper(object): # want (allows test/inheritance.InheritTest4 to pass) self.inherit_condition = sqlutil.join_condition( self.inherits.local_table, - self.local_table, - ignore_nonexistent_tables=True) + self.local_table) self.mapped_table = sql.join( self.inherits.mapped_table, self.local_table, diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 47fc7b08c..e85c82ad7 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -1277,7 +1277,8 @@ class ForeignKey(SchemaItem): raise exc.NoReferencedTableError( "Foreign key associated with column '%s' could not find " "table '%s' with which to generate a " - "foreign key to target column '%s'" % (self.parent, tname, colname)) + "foreign key to target column '%s'" % (self.parent, tname, colname), + tname) table = Table(tname, parenttable.metadata, mustexist=True, schema=schema) @@ -1302,7 +1303,8 @@ class ForeignKey(SchemaItem): raise exc.NoReferencedColumnError( "Could not create ForeignKey '%s' on table '%s': " "table '%s' has no column named '%s'" % ( - self._colspec, parenttable.name, table.name, key)) + self._colspec, parenttable.name, table.name, key), + table.name, key) elif hasattr(self._colspec, '__clause_element__'): _column = self._colspec.__clause_element__() diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 853ec9c5f..1a3f7d2f8 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -187,7 +187,6 @@ def adapt_criterion_to_null(crit, nulls): return visitors.cloned_traverse(crit, {}, {'binary':visit_binary}) - def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None): """create a join condition between two tables or selectables. @@ -203,11 +202,9 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None): between the two selectables. If there are multiple ways to join, or no way to join, an error is raised. - :param ignore_nonexistent_tables: This flag will cause the - function to silently skip over foreign key resolution errors - due to nonexistent tables - the assumption is that these - tables have not yet been defined within an initialization process - and are not significant to the operation. + :param ignore_nonexistent_tables: Deprecated - this + flag is no longer used. Only resolution errors regarding + the two given tables are propagated. :param a_subset: An optional expression that is a sub-component of ``a``. An attempt will be made to join to just this sub-component @@ -228,11 +225,11 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None): key=lambda fk:fk.parent._creation_order): try: col = fk.get_referent(left) - except exc.NoReferencedTableError: - if ignore_nonexistent_tables: - continue - else: + except exc.NoReferenceError, nrte: + if nrte.table_name == left.name: raise + else: + continue if col is not None: crit.append(col == fk.parent) @@ -243,11 +240,13 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None): key=lambda fk:fk.parent._creation_order): try: col = fk.get_referent(b) - except exc.NoReferencedTableError: - if ignore_nonexistent_tables: - continue - else: + except exc.NoReferenceError, nrte: + if nrte.table_name == b.name: raise + else: + # this is totally covered. can't get + # coverage to mark it. + continue if col is not None: crit.append(col == fk.parent) |
