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

psycopg2执行含datetime对象的SQL时报offset附近语法错误如何修复

错误原因
  1. 语法错误根因:你通过str.format()拼接SQL时,直接把Python datetime对象的官方字符串表示(包含tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=330...)这类Python专属语法)塞进了SQL,PostgreSQL完全不识别该格式,直接触发语法报错。
  2. 事务报错根因:第一条UPDATE执行失败后,当前数据库连接的事务就进入了中止状态,你没有做异常回滚就直接执行第二个UPDATE,PostgreSQL会直接拒绝执行,抛出InFailedSqlTransaction错误。
修复方案

使用psycopg2官方推荐的参数绑定机制传递参数,不要手动拼接SQL字符串,psycopg2会自动完成Python类型到PostgreSQL类型的转换,同时避免SQL注入风险,修改后代码如下:

def invalidate_values():
    try:
        for k, v in SYSTEMS.items():
            timestamps = tuple(v[0]['timestamps'])
            # 用%s作为占位符,不要手动拼接参数
            query = '''UPDATE consumers SET is_valid = False WHERE system_id = %s AND time IN %s;'''
            # 参数通过execute的第二个参数按顺序传入,IN子句直接传元组即可被自动适配
            CURSOR.execute(query, (k, timestamps))
        CONNECTION.commit()
        return 1
    except Exception as e:
        # 执行出错就回滚事务,避免影响后续数据库操作
        CONNECTION.rollback()
        raise e

def validate_values():
    try:
        query = "UPDATE consumers SET is_valid = True WHERE created_at >= %s;"
        # 单个参数也要写成元组格式,末尾加逗号避免被拆分为单个字符
        CURSOR.execute(query, (LAST_UNVALIDATED,))
        CONNECTION.commit()
        return 1
    except Exception as e:
        CONNECTION.rollback()
        raise e

如果你的数据库time字段是不带时区的timestamp类型,可以先把Python的datetime对象转换为对应时区的 naive datetime 再传参,或者将字段类型修改为timestamptz和数据对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:54:04