66
66
67
67
if TYPE_CHECKING :
68
68
from sqlalchemy import Table
69
+ from sqlalchemy .sql .expression import (
70
+ Select ,
71
+ TextClause ,
72
+ )
69
73
70
74
71
75
# -----------------------------------------------------------------------------
@@ -80,17 +84,6 @@ def _cleanup_after_generator(generator, exit_stack: ExitStack):
80
84
exit_stack .close ()
81
85
82
86
83
- def _convert_params (sql , params ):
84
- """Convert SQL and params args to DBAPI2.0 compliant format."""
85
- args = [sql ]
86
- if params is not None :
87
- if hasattr (params , "keys" ): # test if params is a mapping
88
- args += [params ]
89
- else :
90
- args += [list (params )]
91
- return args
92
-
93
-
94
87
def _process_parse_dates_argument (parse_dates ):
95
88
"""Process parse_dates argument for read_sql functions"""
96
89
# handle non-list entries for parse_dates gracefully
@@ -217,8 +210,7 @@ def execute(sql, con, params=None):
217
210
if sqlalchemy is not None and isinstance (con , (str , sqlalchemy .engine .Engine )):
218
211
raise TypeError ("pandas.io.sql.execute requires a connection" ) # GH50185
219
212
with pandasSQL_builder (con , need_transaction = True ) as pandas_sql :
220
- args = _convert_params (sql , params )
221
- return pandas_sql .execute (* args )
213
+ return pandas_sql .execute (sql , params )
222
214
223
215
224
216
# -----------------------------------------------------------------------------
@@ -1391,7 +1383,7 @@ def to_sql(
1391
1383
pass
1392
1384
1393
1385
@abstractmethod
1394
- def execute (self , * args , ** kwargs ):
1386
+ def execute (self , sql : str | Select | TextClause , params = None ):
1395
1387
pass
1396
1388
1397
1389
@abstractmethod
@@ -1538,9 +1530,10 @@ def __exit__(self, *args) -> None:
1538
1530
def run_transaction (self ):
1539
1531
yield self .con
1540
1532
1541
- def execute (self , * args , ** kwargs ):
1533
+ def execute (self , sql : str | Select | TextClause , params = None ):
1542
1534
"""Simple passthrough to SQLAlchemy connectable"""
1543
- return self .con .execute (* args , ** kwargs )
1535
+ args = [] if params is None else [params ]
1536
+ return self .con .execute (sql , * args )
1544
1537
1545
1538
def read_table (
1546
1539
self ,
@@ -1710,9 +1703,7 @@ def read_query(
1710
1703
read_sql
1711
1704
1712
1705
"""
1713
- args = _convert_params (sql , params )
1714
-
1715
- result = self .execute (* args )
1706
+ result = self .execute (sql , params )
1716
1707
columns = result .keys ()
1717
1708
1718
1709
if chunksize is not None :
@@ -2170,21 +2161,24 @@ def run_transaction(self):
2170
2161
finally :
2171
2162
cur .close ()
2172
2163
2173
- def execute (self , * args , ** kwargs ):
2164
+ def execute (self , sql : str | Select | TextClause , params = None ):
2165
+ if not isinstance (sql , str ):
2166
+ raise TypeError ("Query must be a string unless using sqlalchemy." )
2167
+ args = [] if params is None else [params ]
2174
2168
cur = self .con .cursor ()
2175
2169
try :
2176
- cur .execute (* args , ** kwargs )
2170
+ cur .execute (sql , * args )
2177
2171
return cur
2178
2172
except Exception as exc :
2179
2173
try :
2180
2174
self .con .rollback ()
2181
2175
except Exception as inner_exc : # pragma: no cover
2182
2176
ex = DatabaseError (
2183
- f"Execution failed on sql: { args [ 0 ] } \n { exc } \n unable to rollback"
2177
+ f"Execution failed on sql: { sql } \n { exc } \n unable to rollback"
2184
2178
)
2185
2179
raise ex from inner_exc
2186
2180
2187
- ex = DatabaseError (f"Execution failed on sql '{ args [ 0 ] } ': { exc } " )
2181
+ ex = DatabaseError (f"Execution failed on sql '{ sql } ': { exc } " )
2188
2182
raise ex from exc
2189
2183
2190
2184
@staticmethod
@@ -2237,9 +2231,7 @@ def read_query(
2237
2231
dtype : DtypeArg | None = None ,
2238
2232
use_nullable_dtypes : bool = False ,
2239
2233
) -> DataFrame | Iterator [DataFrame ]:
2240
-
2241
- args = _convert_params (sql , params )
2242
- cursor = self .execute (* args )
2234
+ cursor = self .execute (sql , params )
2243
2235
columns = [col_desc [0 ] for col_desc in cursor .description ]
2244
2236
2245
2237
if chunksize is not None :
0 commit comments