PostgreSQL如何正确更新timestamp without time zone类型时间字段值
问题原因
- 你使用f-string直接拼接SQL语句时,时间值没有被正确用单引号包裹,PostgreSQL无法识别未加引号的时间字符串为合法的
timestamp without time zone类型值,才会触发语法错误或类型不匹配错误 - 直接拼接SQL还存在SQL注入的安全隐患,属于不推荐的写法
正确解决方案
推荐使用SQLAlchemy的参数绑定写法,框架会自动处理数据类型转换,不需要手动处理引号和类型适配,写法如下:
from sqlalchemy import create_engine, text import pandas as pd from datetime import timedelta # 数据库连接初始化和原有逻辑一致 engine = create_engine('postgresql://postgres:xxx') # 你的业务参数 batch_id = 15 # 无论是pd生成的datetime还是timedelta计算后的时间都可以直接用 correct_datetime = pd.to_datetime('2021-10-05' , format='%Y-%m-%d') # 你提到的第二种计算场景也支持:correct_datetime = df.iloc[-1, 6] + timedelta(days=7) # SQL语句使用占位符,不要直接拼接参数值 sql = text(""" UPDATE my_table SET datetime_opening = :dt_val WHERE id = :batch_id_val """) with engine.begin() as conn: # 执行时传入参数字典,框架自动处理类型适配 conn.execute(sql, {"dt_val": correct_datetime, "batch_id_val": batch_id})
如果确实需要使用字符串拼接的方式(非常不推荐,仅做原理说明),需要手动给时间值包裹单引号:
# 仅做原理演示,生产环境不要使用 correct_datetime = '2021-10-05' sql = f""" UPDATE my_table SET datetime_opening='{correct_datetime}' WHERE id={batch_id} """
这种写法遇到时间值本身包含单引号的场景会再次触发语法错误,同时存在SQL注入风险,仅作为你理解错误原因的参考。
内容的提问来源于stack exchange,提问作者Alessandro Ceccarelli
相关产品推荐
相关产品推荐

