- changed status to resolved
foreign key to a non-table doesn't raise (correctly, consistently)
Issue #2883
resolved
from sqlalchemy import *
m = MetaData()
t1 = Table('t1', m, Column('x', Integer))
t1a = t1.select().alias()
t2 = Table('t2', m, Column('y', Integer, ForeignKey(t1a.c.x)))
print repr(t2)
in 0.8:
File "/Users/classic/tmp/sa084/lib/sqlalchemy/schema.py", line 1337, in __repr__
return "ForeignKey(%r)" % self._get_colspec()
File "/Users/classic/tmp/sa084/lib/sqlalchemy/schema.py", line 1387, in _get_colspec
return "%s.%s" % (_column.table.fullname, _column.key)
AttributeError: 'Alias' object has no attribute 'fullname'
in 0.9, that error would happen, but is blocked by this:
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 1635, in _set_table
self.constraint._set_parent_with_dispatch(table)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/base.py", line 171, in _set_parent_with_dispatch
self._set_parent(parent)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 2444, in _set_parent
self._validate_dest_table(table)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 2417, in _validate_dest_table
table_keys = set([for elem in self._elements.values()](elem._table_key()))
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/schema.py", line 1475, in _table_key
return _column.table.key
AttributeError: 'Alias' object has no attribute 'key'
patch:
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py
index 7bf543a..ec1d430 100644
--- a/lib/sqlalchemy/sql/schema.py
+++ b/lib/sqlalchemy/sql/schema.py
@@ -1340,6 +1340,7 @@ class ForeignKey(SchemaItem):
"""
self._colspec = column
+ self._setup_colspec_arg(column)
# the linked ForeignKeyConstraint.
# ForeignKey will create this when parent Column
@@ -1389,6 +1390,27 @@ class ForeignKey(SchemaItem):
)
return self._schema_item_copy(fk)
+ def _setup_colspec_arg(self, _colspec):
+ if isinstance(self._colspec, util.string_types):
+ self._table_column = None
+ return
+ elif hasattr(self._colspec, '__clause_element__'):
+ _column = self._colspec.__clause_element__()
+ else:
+ _column = self._colspec
+
+ if not isinstance(_column, ColumnClause):
+ raise exc.ArgumentError(
+ "String, Column, or Column-bound argument "
+ "expected, got %r" % _column)
+ elif not isinstance(_column.table, (util.NoneType, TableClause)):
+ raise exc.ArgumentError(
+ "ForeignKey received Column not bound "
+ "to a Table, got: %r" % _column.table
+ )
+ self._table_column = _column
+
+
def _get_colspec(self, schema=None):
"""Return a string based 'column specification' for this
:class:`.ForeignKey`.
@@ -1398,16 +1420,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 +1491,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(
Comments (2)
-
reporter -
reporter - removed milestone
Removing milestone: 0.9.0 (automated comment)
- Log in to comment
84af7e6c22100ef26c5a27185b1d270f5