diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-11 19:48:27 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-11 19:48:27 -0500 |
| commit | 84af7e6c22100ef26c5a27185b1d270f5afb3370 (patch) | |
| tree | 18aa3efba3349c572c381aaf7ed1a74753e11e2d /lib/sqlalchemy/sql/schema.py | |
| parent | 9087157749a0527d6af37e58166793fc7e2f0bf7 (diff) | |
| download | sqlalchemy-84af7e6c22100ef26c5a27185b1d270f5afb3370.tar.gz | |
- The :class:`.ForeignKey` class more aggressively checks the given
column argument. If not a string, it checks that the object is
at least a :class:`.ColumnClause`, or an object that resolves to one,
and that the ``.table`` attribute, if present, refers to a
:class:`.TableClause` or subclass, and not something like an
:class:`.Alias`. Otherwise, a :class:`.ArgumentError` is raised.
[ticket:2883]
Diffstat (limited to 'lib/sqlalchemy/sql/schema.py')
| -rw-r--r-- | lib/sqlalchemy/sql/schema.py | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index 7bf543a61..4d9dc2bda 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -1340,6 +1340,23 @@ class ForeignKey(SchemaItem): """ self._colspec = column + if isinstance(self._colspec, util.string_types): + self._table_column = None + else: + if hasattr(self._colspec, '__clause_element__'): + self._table_column = self._colspec.__clause_element__() + else: + self._table_column = self._colspec + + if not isinstance(self._table_column, ColumnClause): + raise exc.ArgumentError( + "String, Column, or Column-bound argument " + "expected, got %r" % self._table_column) + elif not isinstance(self._table_column.table, (util.NoneType, TableClause)): + raise exc.ArgumentError( + "ForeignKey received Column not bound " + "to a Table, got: %r" % self._table_column.table + ) # the linked ForeignKeyConstraint. # ForeignKey will create this when parent Column @@ -1389,6 +1406,7 @@ class ForeignKey(SchemaItem): ) return self._schema_item_copy(fk) + def _get_colspec(self, schema=None): """Return a string based 'column specification' for this :class:`.ForeignKey`. @@ -1398,16 +1416,25 @@ class ForeignKey(SchemaItem): """ if schema: - return schema + "." + self.column.table.name + \ - "." + self.column.key - elif isinstance(self._colspec, util.string_types): + _schema, tname, colname = self._column_tokens + return "%s.%s.%s" % (schema, tname, colname) + elif self._table_column is not None: + return "%s.%s" % ( + self._table_column.table.fullname, self._table_column.key) + else: return self._colspec - elif hasattr(self._colspec, '__clause_element__'): - _column = self._colspec.__clause_element__() + + + def _table_key(self): + if self._table_column is not None: + if self._table_column.table is None: + return None + else: + return self._table_column.table.key else: - _column = self._colspec + schema, tname, colname = self._column_tokens + return _get_table_key(tname, schema) - return "%s.%s" % (_column.table.fullname, _column.key) target_fullname = property(_get_colspec) @@ -1460,20 +1487,6 @@ class ForeignKey(SchemaItem): schema = None return schema, tname, colname - def _table_key(self): - if isinstance(self._colspec, util.string_types): - schema, tname, colname = self._column_tokens - return _get_table_key(tname, schema) - elif hasattr(self._colspec, '__clause_element__'): - _column = self._colspec.__clause_element__() - else: - _column = self._colspec - - if _column.table is None: - return None - else: - return _column.table.key - def _resolve_col_tokens(self): if self.parent is None: raise exc.InvalidRequestError( |
