Skip to content

Commit fa6c27e

Browse files
committed
✅ add tests for SQLite shorthand foreign key handling
1 parent 6556bc0 commit fa6c27e

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

tests/unit/sqlite3_to_mysql_test.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)