From 9dd48d0911040a80f6bf15739017737ddbf6e3e4 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 6 May 2021 12:51:30 -0400 Subject: [PATCH] narrow rangenotancestor to exclude target heads already present Fixed regression in new revisioning traversal where "alembic downgrade base" would fail if the database itself were clean and unversioned; additionally repairs the case where downgrade would fail if attempting to downgrade to the current head that is already present. Change-Id: I581cab5a17f69d82e41eab147ceb27a38fe4ce1d Fixes: #838 --- alembic/script/revision.py | 8 +++++++- docs/build/unreleased/838.rst | 8 ++++++++ tests/test_version_traversal.py | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 docs/build/unreleased/838.rst diff --git a/alembic/script/revision.py b/alembic/script/revision.py index 4db0a7b7..7fbd670a 100644 --- a/alembic/script/revision.py +++ b/alembic/script/revision.py @@ -1226,6 +1226,7 @@ def _collect_downgrade_revisions( active_revisions = set( self._get_ancestor_nodes(heads, include_dependencies=True) ) + # Emit revisions to drop in reverse topological sorted order. downgrade_revisions.intersection_update(active_revisions) @@ -1235,8 +1236,13 @@ def _collect_downgrade_revisions( active_revisions.difference(self._get_ancestor_nodes(roots)) ) - if not downgrade_revisions: + if ( + target_revision is not None + and not downgrade_revisions + and target_revision not in heads + ): # Empty intersection: target revs are not present. + raise RangeNotAncestorError("Nothing to drop", upper) return downgrade_revisions, heads diff --git a/docs/build/unreleased/838.rst b/docs/build/unreleased/838.rst new file mode 100644 index 00000000..99778004 --- /dev/null +++ b/docs/build/unreleased/838.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, versioning, regression + :tickets: 838 + + Fixed regression in new revisioning traversal where "alembic downgrade + base" would fail if the database itself were clean and unversioned; + additionally repairs the case where downgrade would fail if attempting + to downgrade to the current head that is already present. diff --git a/tests/test_version_traversal.py b/tests/test_version_traversal.py index aad7cce2..f224731f 100644 --- a/tests/test_version_traversal.py +++ b/tests/test_version_traversal.py @@ -50,6 +50,14 @@ def setup_class(cls): def teardown_class(cls): clear_staging_env() + def test_downgrade_base_no_version(self): + self._assert_downgrade("base", [], [], set()) + + def test_downgrade_to_existing(self): + self._assert_downgrade( + self.a.revision, [self.a.revision], [], {self.a.revision} + ) + def test_upgrade_path(self): self._assert_upgrade( self.e.revision,