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

Python3中SQLAlchemy如何正确执行带datetime条件的原生查询

问题原因

你之前的几种写法分别存在这些问题:

  • 前两种字符串拼接SQL的写法,直接把datetime值插入语句后,生成的SQL里时间值没有被单引号包裹,数据库会把2021-06-01 00:00:00识别成带减号的算术表达式,解析到空格后的时间分段就会抛出语法错误,和你看到的syntax error at or near "00"报错完全对应。
  • 第三种参数化写法的错误点在于给SQL语句加了f前缀,f-string会优先解析字符串内容,把你写的%s占位符当成普通字符处理,后续传入的参数无法和占位符匹配,自然执行失败。
  • 额外逻辑问题:纯SELECT查询没有数据修改操作,不需要调用session.commit(),多余的提交操作没有实际作用,还可能引发事务逻辑异常。
正确写法

修正原生SQL参数化写法

核心是去掉SQL字符串前的f前缀,不要手动拼接时间值,直接把解析好的datetime对象作为参数传给execute方法,psycopg2驱动会自动完成时间类型的适配,不需要手动加引号或者转格式:

from datetime import datetime

def get_test(self, start_date, end_date):
    query = 'SELECT * from messages WHERE messages."timeStamp" > %s and messages."timeStamp" < %s;'
    start_dt = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
    end_dt = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")
    res = self.session.execute(query, (start_dt, end_dt))
    return res.fetchall()

使用SQLAlchemy表达式API(推荐)

如果已经定义了messages表对应的模型类,用SQLAlchemy内置的查询接口可以避免手写SQL的引号、占位符错误,写法更简洁安全,也能天然规避SQL注入风险:

from datetime import datetime
# 引入提前定义好的Messages表模型
# from models import Messages

def get_test(self, start_date, end_date):
    start_dt = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
    end_dt = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")
    return self.session.query(Messages).filter(
        Messages.timeStamp > start_dt,
        Messages.timeStamp < end_dt
    ).all()

提示:绝对不要用f-string、字符串format的方式拼接带外部输入的SQL语句,会直接引发SQL注入风险,参数化查询是唯一安全的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:36:28