Skip to content

Commit 5a4339f

Browse files
authored
TST/CLN: Ensure sqlite memory connections are closed (#49154)
* TST/CLN: Use fixtures for TestXSQLite * More sqlite closing
1 parent 94e3987 commit 5a4339f

File tree

1 file changed

+72
-63
lines changed

1 file changed

+72
-63
lines changed

pandas/tests/io/test_sql.py

Lines changed: 72 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"""
1919
from __future__ import annotations
2020

21+
import contextlib
2122
from contextlib import closing
2223
import csv
2324
from datetime import (
@@ -456,8 +457,9 @@ def sqlite_iris_conn(sqlite_iris_engine):
456457

457458
@pytest.fixture
458459
def sqlite_buildin():
459-
with sqlite3.connect(":memory:") as conn:
460-
yield conn
460+
with contextlib.closing(sqlite3.connect(":memory:")) as closing_conn:
461+
with closing_conn as conn:
462+
yield conn
461463

462464

463465
@pytest.fixture
@@ -1561,9 +1563,12 @@ def __init__(self, *args, **kwargs) -> None:
15611563
def __getattr__(self, name):
15621564
return getattr(self.conn, name)
15631565

1564-
conn = MockSqliteConnection(":memory:")
1565-
with tm.assert_produces_warning(UserWarning):
1566-
sql.read_sql("SELECT 1", conn)
1566+
def close(self):
1567+
self.conn.close()
1568+
1569+
with contextlib.closing(MockSqliteConnection(":memory:")) as conn:
1570+
with tm.assert_produces_warning(UserWarning):
1571+
sql.read_sql("SELECT 1", conn)
15671572

15681573
def test_read_sql_delegate(self):
15691574
iris_frame1 = sql.read_sql_query("SELECT * FROM iris", self.conn)
@@ -1945,7 +1950,7 @@ def test_datetime_date(self):
19451950
# comes back as datetime64
19461951
tm.assert_series_equal(result, expected)
19471952

1948-
def test_datetime_time(self):
1953+
def test_datetime_time(self, sqlite_buildin):
19491954
# test support for datetime.time
19501955
df = DataFrame([time(9, 0, 0), time(9, 1, 30)], columns=["a"])
19511956
assert df.to_sql("test_time", self.conn, index=False) == 2
@@ -1954,7 +1959,7 @@ def test_datetime_time(self):
19541959

19551960
# GH8341
19561961
# first, use the fallback to have the sqlite adapter put in place
1957-
sqlite_conn = TestSQLiteFallback.connect()
1962+
sqlite_conn = sqlite_buildin
19581963
assert sql.to_sql(df, "test_time2", sqlite_conn, index=False) == 2
19591964
res = sql.read_sql_query("SELECT * FROM test_time2", sqlite_conn)
19601965
ref = df.applymap(lambda _: _.strftime("%H:%M:%S.%f"))
@@ -2762,21 +2767,17 @@ def tquery(query, con=None):
27622767

27632768

27642769
class TestXSQLite:
2765-
def setup_method(self):
2766-
self.conn = sqlite3.connect(":memory:")
2767-
2768-
def teardown_method(self):
2769-
self.conn.close()
2770-
2771-
def drop_table(self, table_name):
2772-
cur = self.conn.cursor()
2770+
def drop_table(self, table_name, conn):
2771+
cur = conn.cursor()
27732772
cur.execute(f"DROP TABLE IF EXISTS {sql._get_valid_sqlite_name(table_name)}")
2774-
self.conn.commit()
2773+
conn.commit()
27752774

2776-
def test_basic(self):
2775+
def test_basic(self, sqlite_buildin):
27772776
frame = tm.makeTimeDataFrame()
2778-
assert sql.to_sql(frame, name="test_table", con=self.conn, index=False) == 30
2779-
result = sql.read_sql("select * from test_table", self.conn)
2777+
assert (
2778+
sql.to_sql(frame, name="test_table", con=sqlite_buildin, index=False) == 30
2779+
)
2780+
result = sql.read_sql("select * from test_table", sqlite_buildin)
27802781

27812782
# HACK! Change this once indexes are handled properly.
27822783
result.index = frame.index
@@ -2788,47 +2789,52 @@ def test_basic(self):
27882789
frame2 = frame.copy()
27892790
new_idx = Index(np.arange(len(frame2))) + 10
27902791
frame2["Idx"] = new_idx.copy()
2791-
assert sql.to_sql(frame2, name="test_table2", con=self.conn, index=False) == 30
2792-
result = sql.read_sql("select * from test_table2", self.conn, index_col="Idx")
2792+
assert (
2793+
sql.to_sql(frame2, name="test_table2", con=sqlite_buildin, index=False)
2794+
== 30
2795+
)
2796+
result = sql.read_sql(
2797+
"select * from test_table2", sqlite_buildin, index_col="Idx"
2798+
)
27932799
expected = frame.copy()
27942800
expected.index = new_idx
27952801
expected.index.name = "Idx"
27962802
tm.assert_frame_equal(expected, result)
27972803

2798-
def test_write_row_by_row(self):
2804+
def test_write_row_by_row(self, sqlite_buildin):
27992805
frame = tm.makeTimeDataFrame()
28002806
frame.iloc[0, 0] = np.nan
28012807
create_sql = sql.get_schema(frame, "test")
2802-
cur = self.conn.cursor()
2808+
cur = sqlite_buildin.cursor()
28032809
cur.execute(create_sql)
28042810

28052811
ins = "INSERT INTO test VALUES (%s, %s, %s, %s)"
28062812
for _, row in frame.iterrows():
28072813
fmt_sql = format_query(ins, *row)
2808-
tquery(fmt_sql, con=self.conn)
2814+
tquery(fmt_sql, con=sqlite_buildin)
28092815

2810-
self.conn.commit()
2816+
sqlite_buildin.commit()
28112817

2812-
result = sql.read_sql("select * from test", con=self.conn)
2818+
result = sql.read_sql("select * from test", con=sqlite_buildin)
28132819
result.index = frame.index
28142820
tm.assert_frame_equal(result, frame, rtol=1e-3)
28152821

2816-
def test_execute(self):
2822+
def test_execute(self, sqlite_buildin):
28172823
frame = tm.makeTimeDataFrame()
28182824
create_sql = sql.get_schema(frame, "test")
2819-
cur = self.conn.cursor()
2825+
cur = sqlite_buildin.cursor()
28202826
cur.execute(create_sql)
28212827
ins = "INSERT INTO test VALUES (?, ?, ?, ?)"
28222828

28232829
row = frame.iloc[0]
2824-
sql.execute(ins, self.conn, params=tuple(row))
2825-
self.conn.commit()
2830+
sql.execute(ins, sqlite_buildin, params=tuple(row))
2831+
sqlite_buildin.commit()
28262832

2827-
result = sql.read_sql("select * from test", self.conn)
2833+
result = sql.read_sql("select * from test", sqlite_buildin)
28282834
result.index = frame.index[:1]
28292835
tm.assert_frame_equal(result, frame[:1])
28302836

2831-
def test_schema(self):
2837+
def test_schema(self, sqlite_buildin):
28322838
frame = tm.makeTimeDataFrame()
28332839
create_sql = sql.get_schema(frame, "test")
28342840
lines = create_sql.splitlines()
@@ -2840,10 +2846,10 @@ def test_schema(self):
28402846
create_sql = sql.get_schema(frame, "test", keys=["A", "B"])
28412847
lines = create_sql.splitlines()
28422848
assert 'PRIMARY KEY ("A", "B")' in create_sql
2843-
cur = self.conn.cursor()
2849+
cur = sqlite_buildin.cursor()
28442850
cur.execute(create_sql)
28452851

2846-
def test_execute_fail(self):
2852+
def test_execute_fail(self, sqlite_buildin):
28472853
create_sql = """
28482854
CREATE TABLE test
28492855
(
@@ -2853,14 +2859,14 @@ def test_execute_fail(self):
28532859
PRIMARY KEY (a, b)
28542860
);
28552861
"""
2856-
cur = self.conn.cursor()
2862+
cur = sqlite_buildin.cursor()
28572863
cur.execute(create_sql)
28582864

2859-
sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.conn)
2860-
sql.execute('INSERT INTO test VALUES("foo", "baz", 2.567)', self.conn)
2865+
sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', sqlite_buildin)
2866+
sql.execute('INSERT INTO test VALUES("foo", "baz", 2.567)', sqlite_buildin)
28612867

28622868
with pytest.raises(sql.DatabaseError, match="Execution failed on sql"):
2863-
sql.execute('INSERT INTO test VALUES("foo", "bar", 7)', self.conn)
2869+
sql.execute('INSERT INTO test VALUES("foo", "bar", 7)', sqlite_buildin)
28642870

28652871
def test_execute_closed_connection(self):
28662872
create_sql = """
@@ -2872,36 +2878,36 @@ def test_execute_closed_connection(self):
28722878
PRIMARY KEY (a, b)
28732879
);
28742880
"""
2875-
cur = self.conn.cursor()
2876-
cur.execute(create_sql)
2881+
with contextlib.closing(sqlite3.connect(":memory:")) as conn:
2882+
cur = conn.cursor()
2883+
cur.execute(create_sql)
28772884

2878-
sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.conn)
2879-
self.conn.close()
2885+
sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', conn)
28802886

28812887
msg = "Cannot operate on a closed database."
28822888
with pytest.raises(sqlite3.ProgrammingError, match=msg):
2883-
tquery("select * from test", con=self.conn)
2889+
tquery("select * from test", con=conn)
28842890

2885-
def test_keyword_as_column_names(self):
2891+
def test_keyword_as_column_names(self, sqlite_buildin):
28862892
df = DataFrame({"From": np.ones(5)})
2887-
assert sql.to_sql(df, con=self.conn, name="testkeywords", index=False) == 5
2893+
assert sql.to_sql(df, con=sqlite_buildin, name="testkeywords", index=False) == 5
28882894

2889-
def test_onecolumn_of_integer(self):
2895+
def test_onecolumn_of_integer(self, sqlite_buildin):
28902896
# GH 3628
28912897
# a column_of_integers dataframe should transfer well to sql
28922898

28932899
mono_df = DataFrame([1, 2], columns=["c0"])
2894-
assert sql.to_sql(mono_df, con=self.conn, name="mono_df", index=False) == 2
2900+
assert sql.to_sql(mono_df, con=sqlite_buildin, name="mono_df", index=False) == 2
28952901
# computing the sum via sql
2896-
con_x = self.conn
2902+
con_x = sqlite_buildin
28972903
the_sum = sum(my_c0[0] for my_c0 in con_x.execute("select * from mono_df"))
28982904
# it should not fail, and gives 3 ( Issue #3628 )
28992905
assert the_sum == 3
29002906

29012907
result = sql.read_sql("select * from mono_df", con_x)
29022908
tm.assert_frame_equal(result, mono_df)
29032909

2904-
def test_if_exists(self):
2910+
def test_if_exists(self, sqlite_buildin):
29052911
df_if_exists_1 = DataFrame({"col1": [1, 2], "col2": ["A", "B"]})
29062912
df_if_exists_2 = DataFrame({"col1": [3, 4, 5], "col2": ["C", "D", "E"]})
29072913
table_name = "table_if_exists"
@@ -2911,70 +2917,73 @@ def test_if_exists(self):
29112917
with pytest.raises(ValueError, match=msg):
29122918
sql.to_sql(
29132919
frame=df_if_exists_1,
2914-
con=self.conn,
2920+
con=sqlite_buildin,
29152921
name=table_name,
29162922
if_exists="notvalidvalue",
29172923
)
2918-
self.drop_table(table_name)
2924+
self.drop_table(table_name, sqlite_buildin)
29192925

29202926
# test if_exists='fail'
29212927
sql.to_sql(
2922-
frame=df_if_exists_1, con=self.conn, name=table_name, if_exists="fail"
2928+
frame=df_if_exists_1, con=sqlite_buildin, name=table_name, if_exists="fail"
29232929
)
29242930
msg = "Table 'table_if_exists' already exists"
29252931
with pytest.raises(ValueError, match=msg):
29262932
sql.to_sql(
2927-
frame=df_if_exists_1, con=self.conn, name=table_name, if_exists="fail"
2933+
frame=df_if_exists_1,
2934+
con=sqlite_buildin,
2935+
name=table_name,
2936+
if_exists="fail",
29282937
)
29292938
# test if_exists='replace'
29302939
sql.to_sql(
29312940
frame=df_if_exists_1,
2932-
con=self.conn,
2941+
con=sqlite_buildin,
29332942
name=table_name,
29342943
if_exists="replace",
29352944
index=False,
29362945
)
2937-
assert tquery(sql_select, con=self.conn) == [(1, "A"), (2, "B")]
2946+
assert tquery(sql_select, con=sqlite_buildin) == [(1, "A"), (2, "B")]
29382947
assert (
29392948
sql.to_sql(
29402949
frame=df_if_exists_2,
2941-
con=self.conn,
2950+
con=sqlite_buildin,
29422951
name=table_name,
29432952
if_exists="replace",
29442953
index=False,
29452954
)
29462955
== 3
29472956
)
2948-
assert tquery(sql_select, con=self.conn) == [(3, "C"), (4, "D"), (5, "E")]
2949-
self.drop_table(table_name)
2957+
assert tquery(sql_select, con=sqlite_buildin) == [(3, "C"), (4, "D"), (5, "E")]
2958+
self.drop_table(table_name, sqlite_buildin)
29502959

29512960
# test if_exists='append'
29522961
assert (
29532962
sql.to_sql(
29542963
frame=df_if_exists_1,
2955-
con=self.conn,
2964+
con=sqlite_buildin,
29562965
name=table_name,
29572966
if_exists="fail",
29582967
index=False,
29592968
)
29602969
== 2
29612970
)
2962-
assert tquery(sql_select, con=self.conn) == [(1, "A"), (2, "B")]
2971+
assert tquery(sql_select, con=sqlite_buildin) == [(1, "A"), (2, "B")]
29632972
assert (
29642973
sql.to_sql(
29652974
frame=df_if_exists_2,
2966-
con=self.conn,
2975+
con=sqlite_buildin,
29672976
name=table_name,
29682977
if_exists="append",
29692978
index=False,
29702979
)
29712980
== 3
29722981
)
2973-
assert tquery(sql_select, con=self.conn) == [
2982+
assert tquery(sql_select, con=sqlite_buildin) == [
29742983
(1, "A"),
29752984
(2, "B"),
29762985
(3, "C"),
29772986
(4, "D"),
29782987
(5, "E"),
29792988
]
2980-
self.drop_table(table_name)
2989+
self.drop_table(table_name, sqlite_buildin)

0 commit comments

Comments
 (0)