Skip to content

Commit 787f1fa

Browse files
committed
Added tests
1 parent 623411d commit 787f1fa

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

pandas/tests/io/test_sql.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4398,3 +4398,185 @@ def test_xsqlite_if_exists(sqlite_buildin):
43984398
(5, "E"),
43994399
]
44004400
drop_table(table_name, sqlite_buildin)
4401+
4402+
4403+
# -----------------------------------------------------------------------------
4404+
# -- Testing SQL Hints
4405+
4406+
4407+
class TestProcessSQLHints:
4408+
"""Tests for _process_sql_hints helper function."""
4409+
4410+
def test_process_sql_hints_oracle_list(self):
4411+
"""Test hint processing with Oracle dialect and list input."""
4412+
hints = {"oracle": ["APPEND", "PARALLEL"]}
4413+
result = sql._process_sql_hints(hints, "oracle")
4414+
assert result == "/*+ APPEND PARALLEL */"
4415+
4416+
def test_process_sql_hints_oracle_string(self):
4417+
"""Test hint processing with Oracle dialect and string input."""
4418+
hints = {"oracle": "APPEND PARALLEL"}
4419+
result = sql._process_sql_hints(hints, "oracle")
4420+
assert result == "/*+ APPEND PARALLEL */"
4421+
4422+
def test_process_sql_hints_preformatted(self):
4423+
"""Test that pre-formatted hints are returned as-is."""
4424+
hints = {"oracle": "/*+ APPEND PARALLEL */"}
4425+
result = sql._process_sql_hints(hints, "oracle")
4426+
assert result == "/*+ APPEND PARALLEL */"
4427+
4428+
def test_process_sql_hints_case_insensitive(self):
4429+
"""Test that dialect names are case-insensitive."""
4430+
hints = {"ORACLE": ["APPEND"]}
4431+
result = sql._process_sql_hints(hints, "oracle")
4432+
assert result == "/*+ APPEND */"
4433+
4434+
hints = {"oracle": ["APPEND"]}
4435+
result = sql._process_sql_hints(hints, "ORACLE")
4436+
assert result == "/*+ APPEND */"
4437+
4438+
def test_process_sql_hints_no_match(self):
4439+
"""Test that None is returned when dialect doesn't match."""
4440+
hints = {"mysql": "HIGH_PRIORITY"}
4441+
result = sql._process_sql_hints(hints, "oracle")
4442+
assert result is None
4443+
4444+
def test_process_sql_hints_none(self):
4445+
"""Test that None input returns None."""
4446+
result = sql._process_sql_hints(None, "oracle")
4447+
assert result is None
4448+
4449+
def test_process_sql_hints_empty_dict(self):
4450+
"""Test that empty dict returns None."""
4451+
result = sql._process_sql_hints({}, "oracle")
4452+
assert result is None
4453+
4454+
def test_process_sql_hints_mysql(self):
4455+
"""Test hint processing for MySQL dialect."""
4456+
hints = {"mysql": "HIGH_PRIORITY"}
4457+
result = sql._process_sql_hints(hints, "mysql")
4458+
assert result == "HIGH_PRIORITY"
4459+
4460+
def test_process_sql_hints_mssql(self):
4461+
"""Test hint processing for SQL Server dialect."""
4462+
hints = {"mssql": "TABLOCK"}
4463+
result = sql._process_sql_hints(hints, "mssql")
4464+
assert result == "TABLOCK"
4465+
4466+
4467+
@pytest.mark.parametrize("conn", sqlalchemy_connectable)
4468+
def test_to_sql_with_hints_parameter(conn, test_frame1, request):
4469+
"""Test that to_sql accepts hints parameter without error."""
4470+
conn = request.getfixturevalue(conn)
4471+
4472+
with pandasSQL_builder(conn, need_transaction=True) as pandasSQL:
4473+
pandasSQL.to_sql(
4474+
test_frame1, "test_hints", hints={"oracle": ["APPEND"]}, if_exists="replace"
4475+
)
4476+
assert pandasSQL.has_table("test_hints")
4477+
assert count_rows(conn, "test_hints") == len(test_frame1)
4478+
4479+
4480+
@pytest.mark.parametrize("conn", sqlalchemy_connectable)
4481+
def test_to_sql_hints_none_default(conn, test_frame1, request):
4482+
"""Test that hints defaults to None and doesn't break existing code."""
4483+
conn = request.getfixturevalue(conn)
4484+
4485+
with pandasSQL_builder(conn, need_transaction=True) as pandasSQL:
4486+
pandasSQL.to_sql(test_frame1, "test_no_hints")
4487+
assert pandasSQL.has_table("test_no_hints")
4488+
assert count_rows(conn, "test_no_hints") == len(test_frame1)
4489+
4490+
4491+
@pytest.mark.parametrize("conn", sqlalchemy_connectable)
4492+
def test_to_sql_hints_with_method(conn, test_frame1, request):
4493+
"""Test that hints work alongside custom method parameter."""
4494+
conn = request.getfixturevalue(conn)
4495+
4496+
check = []
4497+
4498+
def sample(pd_table, conn, keys, data_iter):
4499+
check.append(1)
4500+
data = [dict(zip(keys, row)) for row in data_iter]
4501+
conn.execute(pd_table.table.insert(), data)
4502+
4503+
with pandasSQL_builder(conn, need_transaction=True) as pandasSQL:
4504+
pandasSQL.to_sql(
4505+
test_frame1,
4506+
"test_hints_method",
4507+
method=sample,
4508+
hints={"oracle": ["APPEND"]},
4509+
)
4510+
assert pandasSQL.has_table("test_hints_method")
4511+
4512+
assert check == [1]
4513+
assert count_rows(conn, "test_hints_method") == len(test_frame1)
4514+
4515+
4516+
@pytest.mark.parametrize("conn", sqlalchemy_connectable)
4517+
@pytest.mark.parametrize("method", [None, "multi"])
4518+
def test_to_sql_hints_with_different_methods(conn, method, test_frame1, request):
4519+
"""Test hints work with different insertion methods."""
4520+
conn = request.getfixturevalue(conn)
4521+
4522+
with pandasSQL_builder(conn, need_transaction=True) as pandasSQL:
4523+
pandasSQL.to_sql(
4524+
test_frame1,
4525+
"test_hints_methods",
4526+
method=method,
4527+
hints={"oracle": ["APPEND", "PARALLEL"]},
4528+
if_exists="replace",
4529+
)
4530+
assert pandasSQL.has_table("test_hints_methods")
4531+
4532+
assert count_rows(conn, "test_hints_methods") == len(test_frame1)
4533+
4534+
4535+
@pytest.mark.parametrize("conn", sqlalchemy_connectable)
4536+
def test_to_sql_hints_multidb_dict(conn, test_frame1, request):
4537+
"""Test that multi-database hints dict works (only matching dialect used)."""
4538+
conn = request.getfixturevalue(conn)
4539+
4540+
hints = {
4541+
"oracle": ["APPEND", "PARALLEL"],
4542+
"mysql": "HIGH_PRIORITY",
4543+
"postgresql": "some_pg_hint",
4544+
"sqlite": "ignored",
4545+
}
4546+
4547+
with pandasSQL_builder(conn, need_transaction=True) as pandasSQL:
4548+
pandasSQL.to_sql(
4549+
test_frame1, "test_multidb_hints", hints=hints, if_exists="replace"
4550+
)
4551+
assert pandasSQL.has_table("test_multidb_hints")
4552+
4553+
assert count_rows(conn, "test_multidb_hints") == len(test_frame1)
4554+
4555+
4556+
def test_to_sql_hints_adbc_not_supported(sqlite_adbc_conn, test_frame1):
4557+
"""Test that ADBC connections raise NotImplementedError for hints."""
4558+
pytest.importorskip("adbc_driver_manager.dbapi")
4559+
4560+
df = test_frame1.copy()
4561+
msg = "'hints' is not implemented for ADBC drivers"
4562+
4563+
with pytest.raises(NotImplementedError, match=msg):
4564+
df.to_sql("test", sqlite_adbc_conn, hints={"oracle": ["APPEND"]})
4565+
4566+
4567+
def test_to_sql_hints_sqlite_builtin(sqlite_buildin, test_frame1):
4568+
"""Test that sqlite builtin connection handles hints gracefully."""
4569+
df = test_frame1.copy()
4570+
4571+
msg = "SQL hints are not supported for SQLite and will be ignored."
4572+
with tm.assert_produces_warning(UserWarning, match=msg):
4573+
result = df.to_sql(
4574+
"test_sqlite_hints",
4575+
sqlite_buildin,
4576+
if_exists="replace",
4577+
hints={"sqlite": "IGNORED"},
4578+
)
4579+
4580+
assert result == len(test_frame1)
4581+
result_df = pd.read_sql("SELECT * FROM test_sqlite_hints", sqlite_buildin)
4582+
assert len(result_df) == len(test_frame1)

0 commit comments

Comments
 (0)