"""
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
)
return self._schema_item_copy(fk)
+
def _get_colspec(self, schema=None):
"""Return a string based 'column specification' for this
:class:`.ForeignKey`.
"""
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)
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(
from sqlalchemy import Integer, String, UniqueConstraint, \
CheckConstraint, ForeignKey, MetaData, Sequence, \
ForeignKeyConstraint, ColumnDefault, Index, event,\
- events, Unicode, types as sqltypes
+ events, Unicode, types as sqltypes, bindparam
from sqlalchemy.testing.schema import Table, Column
from sqlalchemy import schema, exc
import sqlalchemy as tsa
go
)
+ def test_fk_given_non_col(self):
+ not_a_col = bindparam('x')
+ assert_raises_message(
+ exc.ArgumentError,
+ "String, Column, or Column-bound argument expected, got Bind",
+ ForeignKey, not_a_col
+ )
+
+ def test_fk_given_non_col_clauseelem(self):
+ class Foo(object):
+ def __clause_element__(self):
+ return bindparam('x')
+ assert_raises_message(
+ exc.ArgumentError,
+ "String, Column, or Column-bound argument expected, got Bind",
+ ForeignKey, Foo()
+ )
+
+ def test_fk_given_col_non_table(self):
+ t = Table('t', MetaData(), Column('x', Integer))
+ xa = t.alias().c.x
+ assert_raises_message(
+ exc.ArgumentError,
+ "ForeignKey received Column not bound to a Table, got: .*Alias",
+ ForeignKey, xa
+ )
+
+ def test_fk_given_col_non_table_clauseelem(self):
+ t = Table('t', MetaData(), Column('x', Integer))
+ class Foo(object):
+ def __clause_element__(self):
+ return t.alias().c.x
+
+ assert_raises_message(
+ exc.ArgumentError,
+ "ForeignKey received Column not bound to a Table, got: .*Alias",
+ ForeignKey, Foo()
+ )
+
def test_fk_no_such_target_col_error_upfront(self):
meta = MetaData()
a = Table('a', meta, Column('a', Integer))