]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-118221: Always use the default row factory in sqlite3.iterdump() (#118223)
authorErlend E. Aasland <erlend@python.org>
Thu, 25 Apr 2024 08:11:45 +0000 (10:11 +0200)
committerGitHub <noreply@github.com>
Thu, 25 Apr 2024 08:11:45 +0000 (10:11 +0200)
sqlite3.iterdump() depends on the row factory returning resulting rows
as tuples; it will fail with custom row factories like for example a
dict factory.

With this commit, we explicitly reset the row factory of the cursor used
by iterdump(), so we always get predictable results. This does not
affect the row factory of the parent connection.

Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/sqlite3/dump.py
Lib/test/test_sqlite3/test_dump.py
Misc/NEWS.d/next/Library/2024-04-24-12-29-33.gh-issue-118221.2k_bac.rst [new file with mode: 0644]

index 9dcce7dc76ced4880f233908946ed2ba59cf29c8..57e6a3b4f1e6eba0d399d09dbe0df157f36d93b9 100644 (file)
@@ -26,6 +26,7 @@ def _iterdump(connection, *, filter=None):
 
     writeable_schema = False
     cu = connection.cursor()
+    cu.row_factory = None  # Make sure we get predictable results.
     # Disable foreign key constraints, if there is any foreign key violation.
     violations = cu.execute("PRAGMA foreign_key_check").fetchall()
     if violations:
index 7261b7f0dc93d0ab4e117b8acf6c3d7b9761e724..d508f238f84fb5d94bd361e0ba9416c9e3a046f3 100644 (file)
@@ -190,6 +190,21 @@ class DumpTests(MemoryDatabaseMixin, unittest.TestCase):
         got = list(self.cx.iterdump())
         self.assertEqual(expected, got)
 
+    def test_dump_custom_row_factory(self):
+        # gh-118221: iterdump should be able to cope with custom row factories.
+        def dict_factory(cu, row):
+            fields = [col[0] for col in cu.description]
+            return dict(zip(fields, row))
+
+        self.cx.row_factory = dict_factory
+        CREATE_TABLE = "CREATE TABLE test(t);"
+        expected = ["BEGIN TRANSACTION;", CREATE_TABLE, "COMMIT;"]
+
+        self.cu.execute(CREATE_TABLE)
+        actual = list(self.cx.iterdump())
+        self.assertEqual(expected, actual)
+        self.assertEqual(self.cx.row_factory, dict_factory)
+
     def test_dump_virtual_tables(self):
         # gh-64662
         expected = [
diff --git a/Misc/NEWS.d/next/Library/2024-04-24-12-29-33.gh-issue-118221.2k_bac.rst b/Misc/NEWS.d/next/Library/2024-04-24-12-29-33.gh-issue-118221.2k_bac.rst
new file mode 100644 (file)
index 0000000..9b0ea99
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a bug where :func:`sqlite3.iterdump` could fail if a custom :attr:`row
+factory <sqlite3.Connection.row_factory>` was used. Patch by Erlend Aasland.