@@ -1519,6 +1519,99 @@ def execute(self, statement):
15191519 sqlite_cnx .close ()
15201520 sqlite_engine .dispose ()
15211521
1522+ def test_add_foreign_keys_shorthand_references_primary_key (
1523+ self ,
1524+ sqlite_database : str ,
1525+ mysql_database : Engine ,
1526+ mysql_credentials : MySQLCredentials ,
1527+ mocker : MockFixture ,
1528+ ) -> None :
1529+ proc = SQLite3toMySQL ( # type: ignore[call-arg]
1530+ sqlite_file = sqlite_database ,
1531+ mysql_user = mysql_credentials .user ,
1532+ mysql_password = mysql_credentials .password ,
1533+ mysql_host = mysql_credentials .host ,
1534+ mysql_port = mysql_credentials .port ,
1535+ mysql_database = mysql_credentials .database ,
1536+ )
1537+ sqlite_cursor = mocker .MagicMock ()
1538+ sqlite_cursor .fetchall .side_effect = [
1539+ [
1540+ {
1541+ "id" : 0 ,
1542+ "seq" : 0 ,
1543+ "table" : "parent" ,
1544+ "from" : "parent_id" ,
1545+ "to" : "" ,
1546+ "on_delete" : "NO ACTION" ,
1547+ "on_update" : "NO ACTION" ,
1548+ }
1549+ ],
1550+ [
1551+ {"name" : "id" , "pk" : 1 , "hidden" : 0 },
1552+ ],
1553+ ]
1554+ proc ._sqlite_cur = sqlite_cursor
1555+ proc ._sqlite_table_xinfo_support = False
1556+ proc ._mysql_cur = mocker .MagicMock ()
1557+ proc ._mysql = mocker .MagicMock ()
1558+ proc ._logger = mocker .MagicMock ()
1559+
1560+ proc ._add_foreign_keys ("child" )
1561+
1562+ assert proc ._mysql_cur .execute .call_count == 1
1563+ executed_sql : str = proc ._mysql_cur .execute .call_args [0 ][0 ]
1564+ assert "FOREIGN KEY (`parent_id`)" in executed_sql
1565+ assert "REFERENCES `parent`(`id`)" in executed_sql
1566+ proc ._mysql .commit .assert_called_once ()
1567+
1568+ def test_add_foreign_keys_shorthand_pk_mismatch_is_skipped (
1569+ self ,
1570+ sqlite_database : str ,
1571+ mysql_database : Engine ,
1572+ mysql_credentials : MySQLCredentials ,
1573+ mocker : MockFixture ,
1574+ ) -> None :
1575+ proc = SQLite3toMySQL ( # type: ignore[call-arg]
1576+ sqlite_file = sqlite_database ,
1577+ mysql_user = mysql_credentials .user ,
1578+ mysql_password = mysql_credentials .password ,
1579+ mysql_host = mysql_credentials .host ,
1580+ mysql_port = mysql_credentials .port ,
1581+ mysql_database = mysql_credentials .database ,
1582+ )
1583+ sqlite_cursor = mocker .MagicMock ()
1584+ sqlite_cursor .fetchall .side_effect = [
1585+ [
1586+ {
1587+ "id" : 1 ,
1588+ "seq" : 0 ,
1589+ "table" : "parent" ,
1590+ "from" : "parent_id" ,
1591+ "to" : "" ,
1592+ "on_delete" : "NO ACTION" ,
1593+ "on_update" : "NO ACTION" ,
1594+ }
1595+ ],
1596+ [
1597+ {"name" : "id" , "pk" : 1 , "hidden" : 0 },
1598+ {"name" : "second" , "pk" : 2 , "hidden" : 0 },
1599+ ],
1600+ ]
1601+ proc ._sqlite_cur = sqlite_cursor
1602+ proc ._sqlite_table_xinfo_support = False
1603+ proc ._mysql_cur = mocker .MagicMock ()
1604+ proc ._mysql = mocker .MagicMock ()
1605+ proc ._logger = mocker .MagicMock ()
1606+
1607+ proc ._add_foreign_keys ("child" )
1608+
1609+ proc ._mysql_cur .execute .assert_not_called ()
1610+ assert any (
1611+ "unable to resolve referenced primary key columns" in call .args [0 ]
1612+ for call in proc ._logger .warning .call_args_list
1613+ )
1614+
15221615 @pytest .mark .parametrize ("quiet" , [False , True ])
15231616 def test_add_index_duplicate_key_error (
15241617 self ,
0 commit comments