--- /dev/null
+.. change::
+ :tags: usecase, schema
+ :tickets: 7860
+
+ Added support so that the :paramref:`.Table.tometadata.referred_schema_fn`
+ callable passed to :meth:`.Table.to_metadata` may return the value
+ :data:`.BLANK_SCHEMA` to indicate that the referenced foreign key should be
+ reset to None. The :data.`RETAIN_SCHEMA` symbol may also be returned from
+ this function to indicate "no change", which will behave the same as
+ ``None`` currently does which also indicates no change.
+
BLANK_SCHEMA = util.symbol(
"blank_schema",
- """Symbol indicating that a :class:`_schema.Table` or :class:`.Sequence`
+ """Symbol indicating that a :class:`_schema.Table`, :class:`.Sequence`
+ or in some cases a :class:`_schema.ForeignKey` object
should have 'None' for its schema, even if the parent
:class:`_schema.MetaData` has specified a schema.
target schema that we are changing to, the
:class:`_schema.ForeignKeyConstraint` object, and the existing
"target schema" of that constraint. The function should return the
- string schema name that should be applied.
+ string schema name that should be applied. To reset the schema
+ to "none", return the symbol :data:`.BLANK_SCHEMA`. To effect no
+ change, return ``None`` or :data:`.RETAIN_SCHEMA`.
+
+ .. versionchanged:: 1.4.33 The ``referred_schema_fn`` function
+ may return the :data:`.BLANK_SCHEMA` or :data:`.RETAIN_SCHEMA`
+ symbols.
+
E.g.::
def referred_schema_fn(table, to_schema,
argument first passed to the object's constructor.
"""
- if schema:
+ if schema not in (None, RETAIN_SCHEMA):
_schema, tname, colname = self._column_tokens
if table_name is not None:
tname = table_name
- return "%s.%s.%s" % (schema, tname, colname)
+ if schema is BLANK_SCHEMA:
+ return "%s.%s" % (tname, colname)
+ else:
+ return "%s.%s.%s" % (schema, tname, colname)
elif table_name:
schema, tname, colname = self._column_tokens
if schema:
from sqlalchemy.sql import operators
from sqlalchemy.sql.elements import _NONE_NAME
from sqlalchemy.sql.elements import literal_column
+from sqlalchemy.sql.schema import RETAIN_SCHEMA
from sqlalchemy.testing import assert_raises
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import AssertsCompiledSQL
self._assert_fk(t2, "z", "h.t1.x", referred_schema_fn=ref_fn)
+ def test_fk_reset_to_none(self):
+ m = MetaData()
+
+ t2 = Table("t2", m, Column("y", Integer, ForeignKey("p.t1.x")))
+
+ def ref_fn(table, to_schema, constraint, referred_schema):
+ return BLANK_SCHEMA
+
+ self._assert_fk(t2, None, "t1.x", referred_schema_fn=ref_fn)
+
+ @testing.combinations(None, RETAIN_SCHEMA)
+ def test_fk_test_non_return_for_referred_schema(self, sym):
+ m = MetaData()
+
+ t2 = Table("t2", m, Column("y", Integer, ForeignKey("p.t1.x")))
+
+ def ref_fn(table, to_schema, constraint, referred_schema):
+ return sym
+
+ self._assert_fk(t2, None, "p.t1.x", referred_schema_fn=ref_fn)
+
def test_copy_info(self):
m = MetaData()
fk = ForeignKey("t2.id")