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

Jupyter Notebook中SQLAlchemy执行含%符号SQL查询报错求助

解决SQLAlchemy连接MariaDB时DATE_FORMAT中%符号被转义的问题

问题根源是底层MariaDB的DBAPI驱动会将SQL文本中的%识别为参数占位符,自动转义为%%,导致DATE_FORMAT的格式符失效。以下是几种可行的解决方法:

方法一:使用参数绑定传递格式字符串

将DATE_FORMAT的格式字符串通过参数绑定的方式传入,避免被当作占位符转义:

import pandas as pd
from sqlalchemy import text

query = text('''
SELECT COUNT(DISTINCT id_user),
       DATE_FORMAT(time, :format_str) as my
FROM invest_activity
WHERE id_user = 1791237
GROUP BY my
''')

id_user_sample = pd.read_sql(query, con=connection_, params={"format_str": "%m-%Y"})

方法二:用SQLAlchemy表达式构造查询

完全通过SQLAlchemy的API构造DATE_FORMAT函数调用,从根源上避免字符串中的%冲突:

import pandas as pd
from sqlalchemy import func, select, Table, Column, Integer, DateTime, MetaData

# 先映射目标表(如果未定义)
invest_activity = Table(
    'invest_activity',
    MetaData(),
    Column('id_user', Integer),
    Column('time', DateTime),
    # 添加其他实际存在的列
)

# 构造查询语句
stmt = select(
    func.count(func.distinct(invest_activity.c.id_user)),
    func.date_format(invest_activity.c.time, "%m-%Y").label("my")
).where(invest_activity.c.id_user == 1791237).group_by("my")

id_user_sample = pd.read_sql(stmt, con=connection_)

方法三:修改DBAPI的参数风格

修改连接配置,将参数占位符风格改为qmark(即?),这样驱动就不会把%当作占位符处理:

from sqlalchemy import create_engine
import pandas as pd

# 创建引擎时指定参数风格
engine = create_engine(
    'mariadb+mariadbconnector://<用户名>:<密码>@<主机>:<端口>/<数据库名>',
    connect_args={"paramstyle": "qmark"}
)
connection_ = engine.connect()

# 执行原始查询
query = '''
SELECT COUNT(DISTINCT id_user),
       DATE_FORMAT(time, '%m-%Y') as my
FROM invest_activity
WHERE id_user = 1791237
GROUP BY my
'''

id_user_sample = pd.read_sql(text(query), con=connection_)

注意:此方法会改变所有参数占位符的格式,如果查询中有其他参数,需统一改用?作为占位符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:23:00