You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy+psycopg2下pandas.read_sql_query参数替换报dict错误

解决pandas read_sql_query传字典参数报错TypeError: dict is not a sequence的问题

包版本

  • SQLAlchemy 2.0.40
  • pandas 2.2.3
  • psycopg2-binary 2.9.10

问题还原

尝试用pandas原生参数替换执行查询,简化后的SQL语句:

select *
FROM public.bq_results br 
WHERE cast("eventDate" as date) between 
  TO_DATE('%test_start_date', 'YYYYMMDD') AND TO_DATE('%test_end_date', 'YYYYMMDD')
limit 10000

执行以下代码时触发错误:

df = pd.read_sql_query(query, self.__engine, params={"test_start_date": "20250101", "test_end_date": "20250131"})

错误信息:

TypeError: dict is not a sequence

数据库引擎初始化代码:

self.__engine = create_engine(f'postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.database}')

错误原因

psycopg2(PostgreSQL的Python驱动)不支持%test_start_date这种占位符格式,它只认位置占位符%s或者命名占位符%(param_name)s。当前的占位符写法会被驱动识别为普通字符串,同时因为参数传的是字典,驱动期望接收序列(比如列表、元组),所以抛出dict is not a sequence错误。

解决方案

方案1:使用psycopg2命名占位符修改SQL

修改SQL语句中的占位符为%(param_name)s格式,保持params传字典:

select *
FROM public.bq_results br 
WHERE cast("eventDate" as date) between 
  TO_DATE(%(test_start_date)s, 'YYYYMMDD') AND TO_DATE(%(test_end_date)s, 'YYYYMMDD')
limit 10000

执行代码不变:

df = pd.read_sql_query(query, self.__engine, params={"test_start_date": "20250101", "test_end_date": "20250131"})

方案2:用SQLAlchemy文本查询配合命名参数(更规范)

用SQLAlchemy的text()方法包装查询语句,使用:param_name格式的占位符,SQLAlchemy会自动适配底层驱动的参数格式:

from sqlalchemy import text

query = text("""
select *
FROM public.bq_results br 
WHERE cast("eventDate" as date) between 
  TO_DATE(:test_start_date, 'YYYYMMDD') AND TO_DATE(:test_end_date, 'YYYYMMDD')
limit 10000
""")

df = pd.read_sql_query(query, self.__engine, params={"test_start_date": "20250101", "test_end_date": "20250131"})

注意事项

  • 不要直接用字符串拼接生成SQL,会存在SQL注入风险,参数化查询是更安全的方式。
  • 不同数据库驱动的占位符格式不同:PostgreSQL(psycopg2)用%s或%(name)s,MySQL用%s,SQLite用?,而SQLAlchemy的text()方法可以统一用:param_name格式,无需关心底层差异。

内容的提问来源于stack exchange,提问作者Christopher Singer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:49:59