summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/schema.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-12-11 19:48:27 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2013-12-11 19:48:27 -0500
commit84af7e6c22100ef26c5a27185b1d270f5afb3370 (patch)
tree18aa3efba3349c572c381aaf7ed1a74753e11e2d /lib/sqlalchemy/sql/schema.py
parent9087157749a0527d6af37e58166793fc7e2f0bf7 (diff)
downloadsqlalchemy-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.py55
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(