diff --git a/Lib/sqlite3/dump.py b/Lib/sqlite3/dump.py index ead3360ce67608..e12eadd981dcfd 100644 --- a/Lib/sqlite3/dump.py +++ b/Lib/sqlite3/dump.py @@ -26,6 +26,7 @@ def _iterdump(connection): writeable_schema = False cu = connection.cursor() + yield('PRAGMA foreign_keys=OFF;') yield('BEGIN TRANSACTION;') # sqlite_master table contains the SQL CREATE statements for the database. diff --git a/Lib/test/test_sqlite3/test_dump.py b/Lib/test/test_sqlite3/test_dump.py index 3107e1b165d950..3672ba8f96a8ff 100644 --- a/Lib/test/test_sqlite3/test_dump.py +++ b/Lib/test/test_sqlite3/test_dump.py @@ -9,6 +9,15 @@ class DumpTests(MemoryDatabaseMixin, unittest.TestCase): + def checkDump(self, actual, expected): + expected = [ + "PRAGMA foreign_keys=OFF;", + "BEGIN TRANSACTION;", + ] + expected + [ + "COMMIT;", + ] + self.assertEqual(actual, expected) + def test_table_dump(self): expected_sqls = [ """CREATE TABLE "index"("index" blob);""" @@ -42,10 +51,7 @@ def test_table_dump(self): [self.cu.execute(s) for s in expected_sqls] i = self.cx.iterdump() actual_sqls = [s for s in i] - expected_sqls = ['BEGIN TRANSACTION;'] + expected_sqls + \ - ['COMMIT;'] - [self.assertEqual(expected_sqls[i], actual_sqls[i]) - for i in range(len(expected_sqls))] + self.checkDump(actual_sqls, expected_sqls) def test_dump_autoincrement(self): expected = [ @@ -57,15 +63,13 @@ def test_dump_autoincrement(self): # the NULL value should now be automatically be set to 1 expected[1] = expected[1].replace("NULL", "1") - expected.insert(0, "BEGIN TRANSACTION;") expected.extend([ 'DELETE FROM "sqlite_sequence";', 'INSERT INTO "sqlite_sequence" VALUES(\'t1\',1);', - 'COMMIT;', ]) actual = [stmt for stmt in self.cx.iterdump()] - self.assertEqual(expected, actual) + self.checkDump(actual, expected) def test_dump_autoincrement_create_new_db(self): self.cu.execute("BEGIN TRANSACTION") @@ -100,23 +104,17 @@ def __init__(self, cursor, row): def __getitem__(self, index): return self.row[index] self.cx.row_factory = UnorderableRow - CREATE_ALPHA = """CREATE TABLE "alpha" ("one");""" - CREATE_BETA = """CREATE TABLE "beta" ("two");""" - expected = [ - "BEGIN TRANSACTION;", - CREATE_ALPHA, - CREATE_BETA, - "COMMIT;" - ] + CREATE_ALPHA = 'CREATE TABLE "alpha" ("one");' + CREATE_BETA = 'CREATE TABLE "beta" ("two");' + expected = [CREATE_ALPHA, CREATE_BETA] self.cu.execute(CREATE_BETA) self.cu.execute(CREATE_ALPHA) got = list(self.cx.iterdump()) - self.assertEqual(expected, got) + self.checkDump(got, expected) def test_dump_virtual_tables(self): # gh-64662 expected = [ - "BEGIN TRANSACTION;", "PRAGMA writable_schema=ON;", ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" "VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"), @@ -127,11 +125,10 @@ def test_dump_virtual_tables(self): "CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", "CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);", "PRAGMA writable_schema=OFF;", - "COMMIT;" ] self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)") actual = list(self.cx.iterdump()) - self.assertEqual(expected, actual) + self.checkDump(actual, expected) if __name__ == "__main__": diff --git a/Misc/NEWS.d/next/Library/2023-08-25-11-02-27.gh-issue-108364.l1KeRe.rst b/Misc/NEWS.d/next/Library/2023-08-25-11-02-27.gh-issue-108364.l1KeRe.rst new file mode 100644 index 00000000000000..6fe8141848337d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-25-11-02-27.gh-issue-108364.l1KeRe.rst @@ -0,0 +1,2 @@ +:meth:`sqlite3.Connection.iterdump` now ensures that foreign key support is +disabled before dumping the database schema. Patch by Erlend E. Aasland.