Skip to content

Commit

Permalink
- name the include_object hook "foreign_key_constraint"
Browse files Browse the repository at this point in the history
- changelog and other doc updates, fixes #178
- fix drop_constraint() unit tests and add two more for FKs
  • Loading branch information
zzzeek committed Nov 30, 2014
1 parent 96bbcf2 commit 0a47420
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 12 deletions.
4 changes: 2 additions & 2 deletions alembic/autogenerate/compare.py
Expand Up @@ -638,7 +638,7 @@ def _compare_foreign_keys(schema, tname, object_filters, conn_table,

def _add_fk(obj, compare_to):
if _run_filters(
obj.const, obj.name, "foreignkey", False,
obj.const, obj.name, "foreign_key_constraint", False,
compare_to, object_filters):
diffs.append(('add_fk', const.const))

Expand All @@ -651,7 +651,7 @@ def _add_fk(obj, compare_to):

def _remove_fk(obj, compare_to):
if _run_filters(
obj.const, obj.name, "foreignkey", True,
obj.const, obj.name, "foreign_key_constraint", True,
compare_to, object_filters):
diffs.append(('remove_fk', obj.const))
log.info(
Expand Down
9 changes: 7 additions & 2 deletions alembic/environment.py
Expand Up @@ -486,16 +486,21 @@ def my_compare_server_default(context, inspected_column,
as a :class:`~sqlalchemy.schema.Table`,
:class:`~sqlalchemy.schema.Column`,
:class:`~sqlalchemy.schema.Index`
or :class:`~sqlalchemy.schema.UniqueConstraint` object
:class:`~sqlalchemy.schema.UniqueConstraint`,
or :class:`~sqlalchemy.schema.ForeignKeyConstraint` object
* ``name``: the name of the object. This is typically available
via ``object.name``.
* ``type``: a string describing the type of object; currently
``"table"``, ``"column"``, ``"index"`` or ``"unique_constraint"``.
``"table"``, ``"column"``, ``"index"``, ``"unique_constraint"``,
or ``"foreign_key_constraint"``
.. versionadded:: 0.7.0 Support for indexes and unique constraints
within the
:paramref:`~.EnvironmentContext.configure.include_object` hook.
.. versionadded:: 0.7.1 Support for foreign keys within the
:paramref:`~.EnvironmentContext.configure.include_object` hook.
* ``reflected``: ``True`` if the given object was produced based on
table reflection, ``False`` if it's from a local :class:`.MetaData`
object.
Expand Down
6 changes: 5 additions & 1 deletion docs/build/autogenerate.rst
Expand Up @@ -119,6 +119,10 @@ Autogenerate **will detect**:

.. versionadded:: 0.6.1 Support for autogenerate of indexes and unique constraints.

* Basic changes in foreign key constraints

.. versionadded:: 0.7.1 Support for autogenerate of foreign key constraints.

Autogenerate can **optionally detect**:

* Change of column type. This will occur if you set
Expand Down Expand Up @@ -167,7 +171,7 @@ Autogenerate **can not detect**:
Autogenerate can't currently, but **will eventually detect**:

* Some free-standing constraint additions and removals,
like CHECK, FOREIGN KEY, PRIMARY KEY - these are not fully implemented.
like CHECK, PRIMARY KEY - these are not fully implemented.
* Sequence additions, removals - not yet implemented.


Expand Down
10 changes: 10 additions & 0 deletions docs/build/changelog.rst
Expand Up @@ -6,6 +6,16 @@ Changelog
.. changelog::
:version: 0.7.1

.. change::
:tags: feature, autogenerate
:tickets: 178
:pullreq: bitbucket:32

Support for autogenerate of FOREIGN KEY constraints has been added.
These are delivered within the autogenerate process in the same
manner as UNIQUE constraints, including ``include_object`` support.
Big thanks to Ann Kamyshnikova for doing the heavy lifting here.

.. change::
:tags: bug, batch
:pullreq: bitbucket:34
Expand Down
9 changes: 6 additions & 3 deletions tests/test_autogen_fks.py
Expand Up @@ -278,7 +278,8 @@ def test_remove_connection_fk(self):
def include_object(object_, name, type_, reflected, compare_to):
return not (
isinstance(object_, ForeignKeyConstraint) and
type_ == 'foreignkey' and reflected and name == 'fk1')
type_ == 'foreign_key_constraint'
and reflected and name == 'fk1')

diffs = self._fixture(m1, m2, object_filters=[include_object])

Expand Down Expand Up @@ -316,7 +317,8 @@ def test_add_metadata_fk(self):
def include_object(object_, name, type_, reflected, compare_to):
return not (
isinstance(object_, ForeignKeyConstraint) and
type_ == 'foreignkey' and not reflected and name == 'fk1')
type_ == 'foreign_key_constraint'
and not reflected and name == 'fk1')

diffs = self._fixture(m1, m2, object_filters=[include_object])

Expand Down Expand Up @@ -380,7 +382,8 @@ def test_change_fk(self):
def include_object(object_, name, type_, reflected, compare_to):
return not (
isinstance(object_, ForeignKeyConstraint) and
type_ == 'foreignkey' and name == 'fk1'
type_ == 'foreign_key_constraint'
and name == 'fk1'
)

diffs = self._fixture(m1, m2, object_filters=[include_object])
Expand Down
40 changes: 36 additions & 4 deletions tests/test_autogen_render.py
Expand Up @@ -220,7 +220,7 @@ def test_add_unique_constraint_schema(self):
"['code'], schema='CamelSchema')"
)

def test_drop_constraint(self):
def test_drop_unique_constraint(self):
"""
autogenerate.render._drop_constraint
"""
Expand All @@ -233,10 +233,10 @@ def test_drop_constraint(self):
uq = UniqueConstraint(t.c.code, name='uq_test_code')
eq_ignore_whitespace(
autogenerate.render._drop_constraint(uq, self.autogen_context),
"op.drop_constraint('uq_test_code', 'test')"
"op.drop_constraint('uq_test_code', 'test', type_='unique')"
)

def test_drop_constraint_schema(self):
def test_drop_unique_constraint_schema(self):
"""
autogenerate.render._drop_constraint using schema
"""
Expand All @@ -250,7 +250,39 @@ def test_drop_constraint_schema(self):
uq = UniqueConstraint(t.c.code, name='uq_test_code')
eq_ignore_whitespace(
autogenerate.render._drop_constraint(uq, self.autogen_context),
"op.drop_constraint('uq_test_code', 'test', schema='CamelSchema')"
"op.drop_constraint('uq_test_code', 'test', "
"schema='CamelSchema', type_='unique')"
)

def test_drop_fk_constraint(self):
m = MetaData()
Table('a', m, Column('id', Integer, primary_key=True))
b = Table('b', m, Column('a_id', Integer, ForeignKey('a.id')))
fk = ForeignKeyConstraint(['a_id'], ['a.id'], name='fk_a_id')
b.append_constraint(fk)
eq_ignore_whitespace(
autogenerate.render._drop_constraint(fk, self.autogen_context),
"op.drop_constraint('fk_a_id', 'b', type_='foreignkey')"
)

def test_drop_fk_constraint_schema(self):
m = MetaData()
m = MetaData()
Table(
'a', m, Column('id', Integer, primary_key=True),
schema="CamelSchemaTwo")
b = Table(
'b', m, Column('a_id', Integer, ForeignKey('a.id')),
schema="CamelSchemaOne")
fk = ForeignKeyConstraint(
["a_id"],
["CamelSchemaTwo.a.id"], name='fk_a_id')
b.append_constraint(fk)

eq_ignore_whitespace(
autogenerate.render._drop_constraint(fk, self.autogen_context),
"op.drop_constraint('fk_a_id', 'b', schema='CamelSchemaOne', "
"type_='foreignkey')"
)

def test_render_table_upgrade(self):
Expand Down

0 comments on commit 0a47420

Please sign in to comment.