@@ -708,3 +708,105 @@ def test_transform_update_incoming_fks_on_column_rename(fresh_db):
708708 assert fresh_db .execute ("PRAGMA foreign_keys" ).fetchone ()[0 ] == 1
709709 violations = list (fresh_db .execute ("PRAGMA foreign_key_check" ).fetchall ())
710710 assert violations == []
711+
712+
713+ def test_transform_update_incoming_fks_multiple_tables (fresh_db ):
714+ """
715+ Test that update_incoming_fks=True updates FK constraints in multiple tables
716+ when a referenced column is renamed.
717+ """
718+ fresh_db .execute ("PRAGMA foreign_keys=ON" )
719+
720+ # Create authors table with id as PK
721+ fresh_db ["authors" ].insert ({"id" : 1 , "name" : "Alice" }, pk = "id" )
722+
723+ # Create multiple tables with FKs to authors.id
724+ fresh_db ["books" ].insert (
725+ {"id" : 1 , "title" : "Book A" , "author_id" : 1 },
726+ pk = "id" ,
727+ foreign_keys = [("author_id" , "authors" , "id" )],
728+ )
729+ fresh_db ["articles" ].insert (
730+ {"id" : 1 , "headline" : "Article A" , "writer_id" : 1 },
731+ pk = "id" ,
732+ foreign_keys = [("writer_id" , "authors" , "id" )],
733+ )
734+ fresh_db ["quotes" ].insert (
735+ {"id" : 1 , "text" : "Quote A" , "speaker_id" : 1 },
736+ pk = "id" ,
737+ foreign_keys = [("speaker_id" , "authors" , "id" )],
738+ )
739+
740+ # Rename authors.id to authors.author_pk with update_incoming_fks=True
741+ fresh_db ["authors" ].transform (
742+ rename = {"id" : "author_pk" },
743+ update_incoming_fks = True ,
744+ )
745+
746+ # Verify authors column was renamed
747+ assert "author_pk" in fresh_db ["authors" ].columns_dict
748+ assert "id" not in fresh_db ["authors" ].columns_dict
749+
750+ # Verify all FKs were updated
751+ assert fresh_db ["books" ].foreign_keys == [
752+ ForeignKey (table = "books" , column = "author_id" , other_table = "authors" , other_column = "author_pk" )
753+ ]
754+ assert fresh_db ["articles" ].foreign_keys == [
755+ ForeignKey (table = "articles" , column = "writer_id" , other_table = "authors" , other_column = "author_pk" )
756+ ]
757+ assert fresh_db ["quotes" ].foreign_keys == [
758+ ForeignKey (table = "quotes" , column = "speaker_id" , other_table = "authors" , other_column = "author_pk" )
759+ ]
760+
761+ # Verify FK enforcement still works
762+ violations = list (fresh_db .execute ("PRAGMA foreign_key_check" ).fetchall ())
763+ assert violations == []
764+
765+
766+ def test_transform_update_incoming_fks_self_referential (fresh_db ):
767+ """
768+ Test that update_incoming_fks=True handles self-referential FK constraints.
769+ """
770+ fresh_db .execute ("PRAGMA foreign_keys=ON" )
771+
772+ # Create employees table with self-referential FK (manager_id -> id)
773+ fresh_db .execute ("""
774+ CREATE TABLE employees (
775+ id INTEGER PRIMARY KEY,
776+ name TEXT,
777+ manager_id INTEGER REFERENCES employees(id)
778+ )
779+ """ )
780+ fresh_db ["employees" ].insert_all ([
781+ {"id" : 1 , "name" : "CEO" , "manager_id" : None },
782+ {"id" : 2 , "name" : "VP" , "manager_id" : 1 },
783+ {"id" : 3 , "name" : "Dev" , "manager_id" : 2 },
784+ ])
785+
786+ # Verify initial FK
787+ assert fresh_db ["employees" ].foreign_keys == [
788+ ForeignKey (table = "employees" , column = "manager_id" , other_table = "employees" , other_column = "id" )
789+ ]
790+
791+ # Rename employees.id to employees.emp_id with update_incoming_fks=True
792+ fresh_db ["employees" ].transform (
793+ rename = {"id" : "emp_id" },
794+ update_incoming_fks = True ,
795+ )
796+
797+ # Verify column was renamed
798+ assert "emp_id" in fresh_db ["employees" ].columns_dict
799+ assert "id" not in fresh_db ["employees" ].columns_dict
800+
801+ # Verify self-referential FK was updated
802+ assert fresh_db ["employees" ].foreign_keys == [
803+ ForeignKey (table = "employees" , column = "manager_id" , other_table = "employees" , other_column = "emp_id" )
804+ ]
805+
806+ # Verify data integrity
807+ rows = list (fresh_db .execute ("SELECT * FROM employees ORDER BY emp_id" ).fetchall ())
808+ assert rows == [(1 , "CEO" , None ), (2 , "VP" , 1 ), (3 , "Dev" , 2 )]
809+
810+ # Verify FK enforcement still works
811+ violations = list (fresh_db .execute ("PRAGMA foreign_key_check" ).fetchall ())
812+ assert violations == []
0 commit comments