From 89b37248717e2e8c5d45d5be0bc2058694372b16 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 12 Jul 2026 11:45:36 +0000 Subject: [PATCH 1/2] Add test: transform does not cascade-delete referencing records Covers running transform against a table involved in an ON DELETE CASCADE foreign key relationship while PRAGMA foreign_keys is on. Dropping the old table during transform must not trigger the cascade and delete records from the referencing table. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01StxDiBxEbsv8VBmqxamgUV --- tests/test_transform.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/test_transform.py b/tests/test_transform.py index f0f5019a6..284c4fb01 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -432,6 +432,45 @@ def test_transform_verify_foreign_keys(fresh_db): assert fresh_db.conn.execute("PRAGMA foreign_keys").fetchone()[0] +@pytest.mark.parametrize("use_pragma_foreign_keys", [False, True]) +def test_transform_on_delete_cascade_does_not_delete_records( + fresh_db, use_pragma_foreign_keys +): + # Transforming a table drops and recreates it - if another table references + # it with ON DELETE CASCADE and PRAGMA foreign_keys is on, that drop must + # not cascade and delete the referencing records + if use_pragma_foreign_keys: + fresh_db.conn.execute("PRAGMA foreign_keys=ON") + fresh_db.executescript( + """ + CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT); + CREATE TABLE books ( + id INTEGER PRIMARY KEY, + title TEXT, + author_id INTEGER REFERENCES authors(id) ON DELETE CASCADE + ); + """ + ) + fresh_db["authors"].insert({"id": 1, "name": "Ursula K. Le Guin"}) + fresh_db["books"].insert({"id": 1, "title": "The Dispossessed", "author_id": 1}) + # Transform the table on the other end of the cascading foreign key + fresh_db["authors"].transform(rename={"name": "author_name"}) + assert list(fresh_db["authors"].rows) == [ + {"id": 1, "author_name": "Ursula K. Le Guin"} + ] + assert list(fresh_db["books"].rows) == [ + {"id": 1, "title": "The Dispossessed", "author_id": 1} + ] + # Transforming the table with the cascading foreign key should not + # delete its records either + fresh_db["books"].transform(rename={"title": "book_title"}) + assert list(fresh_db["books"].rows) == [ + {"id": 1, "book_title": "The Dispossessed", "author_id": 1} + ] + if use_pragma_foreign_keys: + assert fresh_db.conn.execute("PRAGMA foreign_keys").fetchone()[0] + + def test_transform_add_foreign_keys_from_scratch(fresh_db): _add_country_city_continent(fresh_db) fresh_db["places"].insert(_CAVEAU) From 8ca780c30d1fe359160c989bd6ff0e7d9d963dc6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 12 Jul 2026 11:55:08 +0000 Subject: [PATCH 2/2] Apply Black Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01StxDiBxEbsv8VBmqxamgUV --- tests/test_transform.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_transform.py b/tests/test_transform.py index 284c4fb01..3cc5ba60c 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -441,16 +441,14 @@ def test_transform_on_delete_cascade_does_not_delete_records( # not cascade and delete the referencing records if use_pragma_foreign_keys: fresh_db.conn.execute("PRAGMA foreign_keys=ON") - fresh_db.executescript( - """ + fresh_db.executescript(""" CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT); CREATE TABLE books ( id INTEGER PRIMARY KEY, title TEXT, author_id INTEGER REFERENCES authors(id) ON DELETE CASCADE ); - """ - ) + """) fresh_db["authors"].insert({"id": 1, "name": "Ursula K. Le Guin"}) fresh_db["books"].insert({"id": 1, "title": "The Dispossessed", "author_id": 1}) # Transform the table on the other end of the cascading foreign key