Skip to content

Commit c51b7ad

Browse files
BUG/TST: wrap plain SQL with sqlalchemy.text() in SQLAlchemy read_query; add modulo/LIKE tests
1 parent e79f156 commit c51b7ad

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,7 @@ doc/source/savefig/
141141
# Pyodide/WASM related files #
142142
##############################
143143
/.pyodide-xbuildenv-*
144+
145+
venv*/
146+
.venv*/
147+
*.log

pandas/io/sql.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@
9494
# -- Helper functions
9595

9696

97+
def _sa_text_if_string(stmt):
98+
"""Wrap plain SQL strings in sqlalchemy.text()."""
99+
try:
100+
import sqlalchemy as sa
101+
except Exception:
102+
return stmt
103+
return sa.text(stmt) if isinstance(stmt, str) else stmt
104+
105+
97106
def _process_parse_dates_argument(parse_dates):
98107
"""Process parse_dates argument for read_sql functions"""
99108
# handle non-list entries for parse_dates gracefully
@@ -1848,7 +1857,9 @@ def read_query(
18481857
read_sql_table : Read SQL database table into a DataFrame.
18491858
read_sql
18501859
1860+
18511861
"""
1862+
sql = _sa_text_if_string(sql)
18521863
result = self.execute(sql, params)
18531864
columns = result.keys()
18541865

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# pandas/tests/io/sql/test_percent_patterns.py
2+
import os
3+
4+
import pytest
5+
6+
sa = pytest.importorskip("sqlalchemy")
7+
8+
PG = os.environ.get("PANDAS_TEST_POSTGRES_URI")
9+
URL = PG or "sqlite+pysqlite:///:memory:"
10+
11+
12+
def _eng():
13+
return sa.create_engine(URL)
14+
15+
16+
def test_text_modulo():
17+
import pandas as pd
18+
19+
with _eng().connect() as c:
20+
df = pd.read_sql(sa.text("SELECT 5 % 2 AS r"), c)
21+
assert df.iloc[0, 0] == 1
22+
23+
24+
def test_like_single_percent():
25+
import pandas as pd
26+
27+
with _eng().connect() as c:
28+
df = pd.read_sql(
29+
sa.text("SELECT 'John' AS fullname WHERE 'John' LIKE 'John%'"),
30+
c,
31+
)
32+
assert len(df) == 1
33+
34+
35+
def test_sqlalchemy_expr_percent_operator():
36+
from sqlalchemy import (
37+
literal,
38+
select,
39+
)
40+
41+
import pandas as pd
42+
43+
with _eng().connect() as c:
44+
df = pd.read_sql(select((literal(7) % literal(3)).label("r")), c)
45+
assert df.iloc[0, 0] == 1

0 commit comments

Comments
 (0)