Skip to content

Commit bbab54a

Browse files
authored
compat: sqlalchemy deprecations (#40471)
1 parent d83d715 commit bbab54a

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

pandas/io/sql.py

+35-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
datetime,
1010
time,
1111
)
12+
from distutils.version import LooseVersion
1213
from functools import partial
1314
import re
1415
from typing import (
@@ -77,6 +78,16 @@ def _is_sqlalchemy_connectable(con):
7778
return False
7879

7980

81+
def _gt14() -> bool:
82+
"""
83+
Check if sqlalchemy.__version__ is at least 1.4.0, when several
84+
deprecations were made.
85+
"""
86+
import sqlalchemy
87+
88+
return LooseVersion(sqlalchemy.__version__) >= LooseVersion("1.4.0")
89+
90+
8091
def _convert_params(sql, params):
8192
"""Convert SQL and params args to DBAPI2.0 compliant format."""
8293
args = [sql]
@@ -823,7 +834,10 @@ def sql_schema(self):
823834

824835
def _execute_create(self):
825836
# Inserting table into database, add to MetaData object
826-
self.table = self.table.tometadata(self.pd_sql.meta)
837+
if _gt14():
838+
self.table = self.table.to_metadata(self.pd_sql.meta)
839+
else:
840+
self.table = self.table.tometadata(self.pd_sql.meta)
827841
self.table.create()
828842

829843
def create(self):
@@ -1596,9 +1610,17 @@ def to_sql(
15961610
# Only check when name is not a number and name is not lower case
15971611
engine = self.connectable.engine
15981612
with self.connectable.connect() as conn:
1599-
table_names = engine.table_names(
1600-
schema=schema or self.meta.schema, connection=conn
1601-
)
1613+
if _gt14():
1614+
from sqlalchemy import inspect
1615+
1616+
insp = inspect(conn)
1617+
table_names = insp.get_table_names(
1618+
schema=schema or self.meta.schema
1619+
)
1620+
else:
1621+
table_names = engine.table_names(
1622+
schema=schema or self.meta.schema, connection=conn
1623+
)
16021624
if name not in table_names:
16031625
msg = (
16041626
f"The provided table name '{name}' is not found exactly as "
@@ -1613,9 +1635,15 @@ def tables(self):
16131635
return self.meta.tables
16141636

16151637
def has_table(self, name: str, schema: Optional[str] = None):
1616-
return self.connectable.run_callable(
1617-
self.connectable.dialect.has_table, name, schema or self.meta.schema
1618-
)
1638+
if _gt14():
1639+
import sqlalchemy as sa
1640+
1641+
insp = sa.inspect(self.connectable)
1642+
return insp.has_table(name, schema or self.meta.schema)
1643+
else:
1644+
return self.connectable.run_callable(
1645+
self.connectable.dialect.has_table, name, schema or self.meta.schema
1646+
)
16191647

16201648
def get_table(self, table_name: str, schema: Optional[str] = None):
16211649
schema = schema or self.meta.schema

pandas/tests/io/test_sql.py

+19-5
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@
5252

5353
import pandas.io.sql as sql
5454
from pandas.io.sql import (
55+
_gt14,
5556
read_sql_query,
5657
read_sql_table,
5758
)
5859

5960
try:
6061
import sqlalchemy
62+
from sqlalchemy import inspect
6163
from sqlalchemy.ext import declarative
6264
from sqlalchemy.orm import session as sa_session
6365
import sqlalchemy.schema
@@ -1487,7 +1489,11 @@ def test_create_table(self):
14871489
pandasSQL = sql.SQLDatabase(temp_conn)
14881490
pandasSQL.to_sql(temp_frame, "temp_frame")
14891491

1490-
assert temp_conn.has_table("temp_frame")
1492+
if _gt14():
1493+
insp = inspect(temp_conn)
1494+
assert insp.has_table("temp_frame")
1495+
else:
1496+
assert temp_conn.has_table("temp_frame")
14911497

14921498
def test_drop_table(self):
14931499
temp_conn = self.connect()
@@ -1499,11 +1505,18 @@ def test_drop_table(self):
14991505
pandasSQL = sql.SQLDatabase(temp_conn)
15001506
pandasSQL.to_sql(temp_frame, "temp_frame")
15011507

1502-
assert temp_conn.has_table("temp_frame")
1508+
if _gt14():
1509+
insp = inspect(temp_conn)
1510+
assert insp.has_table("temp_frame")
1511+
else:
1512+
assert temp_conn.has_table("temp_frame")
15031513

15041514
pandasSQL.drop_table("temp_frame")
15051515

1506-
assert not temp_conn.has_table("temp_frame")
1516+
if _gt14():
1517+
assert not insp.has_table("temp_frame")
1518+
else:
1519+
assert not temp_conn.has_table("temp_frame")
15071520

15081521
def test_roundtrip(self):
15091522
self._roundtrip()
@@ -1843,9 +1856,10 @@ def test_nan_string(self):
18431856
tm.assert_frame_equal(result, df)
18441857

18451858
def _get_index_columns(self, tbl_name):
1846-
from sqlalchemy.engine import reflection
1859+
from sqlalchemy import inspect
1860+
1861+
insp = inspect(self.conn)
18471862

1848-
insp = reflection.Inspector.from_engine(self.conn)
18491863
ixs = insp.get_indexes(tbl_name)
18501864
ixs = [i["column_names"] for i in ixs]
18511865
return ixs

0 commit comments

Comments
 (0)