summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/schema.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/schema.py')
-rw-r--r--lib/sqlalchemy/schema.py53
1 files changed, 45 insertions, 8 deletions
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index 75bbfd070..5f82a0200 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -806,7 +806,11 @@ class Column(SchemaItem, expression.ColumnClause):
for fk in col.foreign_keys:
col.foreign_keys.remove(fk)
table.foreign_keys.remove(fk)
- table.constraints.remove(fk.constraint)
+ if fk.constraint in table.constraints:
+ # this might have been removed
+ # already, if it's a composite constraint
+ # and more than one col being replaced
+ table.constraints.remove(fk.constraint)
table._columns.replace(self)
@@ -1019,7 +1023,20 @@ class ForeignKey(SchemaItem):
return "ForeignKey(%r)" % self._get_colspec()
def copy(self, schema=None):
- """Produce a copy of this ForeignKey object."""
+ """Produce a copy of this :class:`ForeignKey` object.
+
+ The new :class:`ForeignKey` will not be bound
+ to any :class:`Column`.
+
+ This method is usually used by the internal
+ copy procedures of :class:`Column`, :class:`Table`,
+ and :class:`MetaData`.
+
+ :param schema: The returned :class:`ForeignKey` will
+ reference the original table and column name, qualified
+ by the given string schema name.
+
+ """
return ForeignKey(
self._get_colspec(schema=schema),
@@ -1033,6 +1050,12 @@ class ForeignKey(SchemaItem):
)
def _get_colspec(self, schema=None):
+ """Return a string based 'column specification' for this :class:`ForeignKey`.
+
+ This is usually the equivalent of the string-based "tablename.colname"
+ argument first passed to the object's constructor.
+
+ """
if schema:
return schema + "." + self.column.table.name + \
"." + self.column.key
@@ -1048,15 +1071,16 @@ class ForeignKey(SchemaItem):
target_fullname = property(_get_colspec)
def references(self, table):
- """Return True if the given table is referenced by this ForeignKey."""
+ """Return True if the given :class:`Table` is referenced by this :class:`ForeignKey`."""
return table.corresponding_column(self.column) is not None
def get_referent(self, table):
- """Return the column in the given table referenced by this ForeignKey.
+ """Return the :class:`.Column` in the given :class:`.Table`
+ referenced by this :class:`ForeignKey`.
- Returns None if this ``ForeignKey`` does not reference the given
- table.
+ Returns None if this :class:`ForeignKey` does not reference the given
+ :class:`Table`.
"""
@@ -1064,6 +1088,18 @@ class ForeignKey(SchemaItem):
@util.memoized_property
def column(self):
+ """Return the target :class:`.Column` referenced by this :class:`.ForeignKey`.
+
+ If this :class:`ForeignKey` was created using a
+ string-based target column specification, this
+ attribute will on first access initiate a resolution
+ process to locate the referenced remote
+ :class:`.Column`. The resolution process traverses
+ to the parent :class:`.Column`, :class:`.Table`, and
+ :class:`.MetaData` to proceed - if any of these aren't
+ yet present, an error is raised.
+
+ """
# ForeignKey inits its remote column as late as possible, so tables
# can be defined without dependencies
if isinstance(self._colspec, basestring):
@@ -1108,8 +1144,9 @@ class ForeignKey(SchemaItem):
if _get_table_key(tname, schema) not in parenttable.metadata:
raise exc.NoReferencedTableError(
- "Could not find table '%s' with which to generate a "
- "foreign key" % tname)
+ "Foreign key assocated with column '%s' could not find "
+ "table '%s' with which to generate a "
+ "foreign key to target column '%s'" % (self.parent, tname, colname))
table = Table(tname, parenttable.metadata,
mustexist=True, schema=schema)