]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Respects ResultProxy.supports_sane_rowcount()
authorKe Zhu <kzhu@us.ibm.com>
Fri, 28 Feb 2020 21:00:57 +0000 (16:00 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 1 Mar 2020 16:14:58 +0000 (11:14 -0500)
The check for matched rowcount when the alembic_version table is updated or
deleted from is now conditional based on whether or not the dialect
supports the concept of "rowcount" for UPDATE or DELETE rows matched.  Some
third party dialects do not support this concept.  Pull request courtesy Ke
Zhu.

Closes: #667
Pull-request: https://github.com/sqlalchemy/alembic/pull/667
Pull-request-sha: a0d45ed0f5de582314faae2210eeec881670488e

Change-Id: I09c9b540d8e21a94728085270eb20ba2273cbdb1

alembic/runtime/migration.py
docs/build/unreleased/rowcount.rst [new file with mode: 0644]
tests/test_version_table.py

index 0a1e646d321c026a0335ed3e54f5a7c64ecd1a6e..49eef713548fdc82beac285daf7ac880c7c25d1f 100644 (file)
@@ -676,7 +676,11 @@ class HeadMaintainer(object):
                 == literal_column("'%s'" % version)
             )
         )
-        if not self.context.as_sql and ret.rowcount != 1:
+        if (
+            not self.context.as_sql
+            and self.context.dialect.supports_sane_rowcount
+            and ret.rowcount != 1
+        ):
             raise util.CommandError(
                 "Online migration expected to match one "
                 "row when deleting '%s' in '%s'; "
@@ -697,7 +701,11 @@ class HeadMaintainer(object):
                 == literal_column("'%s'" % from_)
             )
         )
-        if not self.context.as_sql and ret.rowcount != 1:
+        if (
+            not self.context.as_sql
+            and self.context.dialect.supports_sane_rowcount
+            and ret.rowcount != 1
+        ):
             raise util.CommandError(
                 "Online migration expected to match one "
                 "row when updating '%s' to '%s' in '%s'; "
diff --git a/docs/build/unreleased/rowcount.rst b/docs/build/unreleased/rowcount.rst
new file mode 100644 (file)
index 0000000..8e7830a
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, environment
+
+    The check for matched rowcount when the alembic_version table is updated or
+    deleted from is now conditional based on whether or not the dialect
+    supports the concept of "rowcount" for UPDATE or DELETE rows matched.  Some
+    third party dialects do not support this concept.  Pull request courtesy Ke
+    Zhu.
index 34bdfabf26d61642f0896573a718b0d47a745006..1801346ce3c22f571cb405c30f5f528b1ef12b38 100644 (file)
@@ -262,6 +262,14 @@ class UpdateRevTest(TestBase):
             _up("x", "b"),
         )
 
+    def test_update_no_match_no_sane_rowcount(self):
+        self.updater.update_to_step(_up(None, "a", True))
+        self.updater.heads.add("x")
+        with mock.patch.object(
+            self.connection.dialect, "supports_sane_rowcount", False
+        ):
+            self.updater.update_to_step(_up("x", "b"))
+
     def test_update_multi_match(self):
         self.connection.execute(version_table.insert(), version_num="a")
         self.connection.execute(version_table.insert(), version_num="a")
@@ -275,6 +283,16 @@ class UpdateRevTest(TestBase):
             _up("a", "b"),
         )
 
+    def test_update_multi_match_no_sane_rowcount(self):
+        self.connection.execute(version_table.insert(), version_num="a")
+        self.connection.execute(version_table.insert(), version_num="a")
+
+        self.updater.heads.add("a")
+        with mock.patch.object(
+            self.connection.dialect, "supports_sane_rowcount", False
+        ):
+            self.updater.update_to_step(_up("a", "b"))
+
     def test_delete_no_match(self):
         self.updater.update_to_step(_up(None, "a", True))
 
@@ -287,6 +305,15 @@ class UpdateRevTest(TestBase):
             _down("x", None, True),
         )
 
+    def test_delete_no_matchno_sane_rowcount(self):
+        self.updater.update_to_step(_up(None, "a", True))
+
+        self.updater.heads.add("x")
+        with mock.patch.object(
+            self.connection.dialect, "supports_sane_rowcount", False
+        ):
+            self.updater.update_to_step(_down("x", None, True))
+
     def test_delete_multi_match(self):
         self.connection.execute(version_table.insert(), version_num="a")
         self.connection.execute(version_table.insert(), version_num="a")
@@ -299,3 +326,13 @@ class UpdateRevTest(TestBase):
             self.updater.update_to_step,
             _down("a", None, True),
         )
+
+    def test_delete_multi_match_no_sane_rowcount(self):
+        self.connection.execute(version_table.insert(), version_num="a")
+        self.connection.execute(version_table.insert(), version_num="a")
+
+        self.updater.heads.add("a")
+        with mock.patch.object(
+            self.connection.dialect, "supports_sane_rowcount", False
+        ):
+            self.updater.update_to_step(_down("a", None, True))