Fix tuple parameter handling for SQLAlchemy 2.0 pooled queries
Fixes 'List of argument must consist only of dictionaries' error when running parallel queries with ODBC-style ? placeholders. The issue occurs because SQLAlchemy 2.0's text() expects named parameters (dict) but the code was passing positional parameters (tuples). Solution: - Detect tuple parameters in _execute_query_pooled - Convert tuples to dict with keys p1, p2, p3... - Replace ? placeholders with :p1, :p2... in the query string - Pass converted dict to conn.execute() This maintains backward compatibility with single-connection mode which uses pyodbc and handles tuple parameters natively. Affected queries: - table_exists (2 params: schema, table) - get_columns (2 params: schema, table) - get_primary_keys (2 params: schema, table)
This commit is contained in:
@@ -75,6 +75,24 @@ class QueryExecutor:
|
||||
raise ValueError("Only SELECT queries are allowed (READ ONLY)")
|
||||
|
||||
try:
|
||||
# Convert tuple params to dict for SQLAlchemy 2.0 compatibility
|
||||
if isinstance(params, tuple):
|
||||
# Map positional params to p1, p2, p3...
|
||||
params_dict = {f"p{i}": val for i, val in enumerate(params, 1)}
|
||||
# Replace ? placeholders with :p1, :p2... by iterating
|
||||
query_parts = []
|
||||
last_pos = 0
|
||||
param_index = 1
|
||||
for char_pos, char in enumerate(query):
|
||||
if char == '?':
|
||||
query_parts.append(query[last_pos:char_pos])
|
||||
query_parts.append(f':p{param_index}')
|
||||
last_pos = char_pos + 1
|
||||
param_index += 1
|
||||
query_parts.append(query[last_pos:])
|
||||
query = ''.join(query_parts)
|
||||
params = params_dict
|
||||
|
||||
with self._engine.connect() as conn:
|
||||
result = conn.execute(text(query), params or {})
|
||||
df = pd.DataFrame(result.all(), columns=result.keys())
|
||||
|
||||
Reference in New Issue
Block a user