Skip to content

Commit fa8a5ca

Browse files
Merge pull request #7326 from jorisvandenbossche/sql-delegation
BUG: fix read_sql delegation for queries without select statement (GH7324)
2 parents e0fc211 + 013a068 commit fa8a5ca

File tree

3 files changed

+41
-15
lines changed

3 files changed

+41
-15
lines changed

doc/source/v0.14.1.txt

+3
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,6 @@ Bug Fixes
117117
- Bug in ``MultiIndex.append``, ``concat`` and ``pivot_table`` don't preserve timezone (:issue:`6606`)
118118
- Bug in ``.loc`` with a list of indexers on a single-multi index level (that is not nested) (:issue:`7349`)
119119
- Bug in ``Series.map`` when mapping a dict with tuple keys of different lengths (:issue:`7333`)
120+
- Bug all ``StringMethods`` now work on empty Series (:issue:`7242`)
121+
- Fix delegation of `read_sql` to `read_sql_query` when query does not contain
122+
'select' (:issue:`7324`).

pandas/io/sql.py

+7-14
Original file line numberDiff line numberDiff line change
@@ -374,26 +374,19 @@ def read_sql(sql, con, index_col=None, coerce_float=True, params=None,
374374
"""
375375
pandas_sql = pandasSQL_builder(con)
376376

377-
if 'select' in sql.lower():
378-
try:
379-
if pandas_sql.has_table(sql):
380-
return pandas_sql.read_table(
381-
sql, index_col=index_col, coerce_float=coerce_float,
382-
parse_dates=parse_dates, columns=columns)
383-
except:
384-
pass
385-
377+
if isinstance(pandas_sql, PandasSQLLegacy):
386378
return pandas_sql.read_sql(
387379
sql, index_col=index_col, params=params,
388380
coerce_float=coerce_float, parse_dates=parse_dates)
389-
else:
390-
if isinstance(pandas_sql, PandasSQLLegacy):
391-
raise ValueError("Reading a table with read_sql is not supported "
392-
"for a DBAPI2 connection. Use an SQLAlchemy "
393-
"engine or specify an sql query")
381+
382+
if pandas_sql.has_table(sql):
394383
return pandas_sql.read_table(
395384
sql, index_col=index_col, coerce_float=coerce_float,
396385
parse_dates=parse_dates, columns=columns)
386+
else:
387+
return pandas_sql.read_sql(
388+
sql, index_col=index_col, params=params,
389+
coerce_float=coerce_float, parse_dates=parse_dates)
397390

398391

399392
def to_sql(frame, name, con, flavor='sqlite', if_exists='fail', index=True,

pandas/io/tests/test_sql.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ def test_read_sql_delegate(self):
671671
"read_sql and read_sql_query have not the same"
672672
" result with a query")
673673

674-
self.assertRaises(ValueError, sql.read_sql, 'iris', self.conn)
674+
self.assertRaises(sql.DatabaseError, sql.read_sql, 'iris', self.conn)
675675

676676
def test_safe_names_warning(self):
677677
# GH 6798
@@ -1078,6 +1078,36 @@ def test_default_type_conversion(self):
10781078
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
10791079
"BoolColWithNull loaded with incorrect type")
10801080

1081+
def test_read_procedure(self):
1082+
# see GH7324. Although it is more an api test, it is added to the
1083+
# mysql tests as sqlite does not have stored procedures
1084+
df = DataFrame({'a': [1, 2, 3], 'b':[0.1, 0.2, 0.3]})
1085+
df.to_sql('test_procedure', self.conn, index=False)
1086+
1087+
proc = """DROP PROCEDURE IF EXISTS get_testdb;
1088+
1089+
CREATE PROCEDURE get_testdb ()
1090+
1091+
BEGIN
1092+
SELECT * FROM test_procedure;
1093+
END"""
1094+
1095+
connection = self.conn.connect()
1096+
trans = connection.begin()
1097+
try:
1098+
r1 = connection.execute(proc)
1099+
trans.commit()
1100+
except:
1101+
trans.rollback()
1102+
raise
1103+
1104+
res1 = sql.read_sql_query("CALL get_testdb();", self.conn)
1105+
tm.assert_frame_equal(df, res1)
1106+
1107+
# test delegation to read_sql_query
1108+
res2 = sql.read_sql("CALL get_testdb();", self.conn)
1109+
tm.assert_frame_equal(df, res2)
1110+
10811111

10821112
class TestPostgreSQLAlchemy(_TestSQLAlchemy):
10831113
"""

0 commit comments

Comments
 (0)