Python向PostgreSQL插入datetime时报TypeError字符串格式化错误
问题原因
该报错与PostgreSQL表字段类型无关,是cursor.execute()方法传参的语法错误导致:
Python中(start_time)不属于单元素元组,只是被括号包裹的普通字符串对象。psycopg2会将传入的第二个参数识别为参数序列,遍历字符串的每个字符去匹配SQL中的%s占位符,最终因参数数量不匹配触发TypeError: not all arguments converted during string formatting报错。
修复方法
- 修正传参的元组写法:Python单元素元组必须在元素末尾添加逗号,将传参部分从
(start_time)改为(start_time,)即可解决语法问题,修正后的执行语句如下:
cursor.execute("""INSERT INTO table01(start_time_str) VALUES(%s);""", (start_time,))
- 优化实现逻辑:不需要手动将datetime对象转为字符串,psycopg2原生支持Python标准库的datetime类型自动适配PostgreSQL的timestamp类字段,直接传入原始datetime对象即可,既省去格式转换步骤,也能避免手动格式化带来的时区、精度不匹配问题。优化后的完整参考代码如下:
from datetime import datetime, timedelta import psycopg2 # 直接生成datetime对象,无需调用strftime转字符串 start_time = datetime.now() - timedelta(hours=33) conn = psycopg2.connect(... 填入你的数据库连接参数 ...) cursor = conn.cursor() # 注意单元素传参时元组末尾必须加逗号 cursor.execute("INSERT INTO table01(start_time_str) VALUES(%s);", (start_time,)) conn.commit() # 操作完成后记得关闭游标和连接释放资源 cursor.close() conn.close()
注意事项
- 使用psycopg2执行带参数的SQL时,传入的参数序列必须符合Python序列语法:
- 无参数时传入空元组
() - 单参数时必须保留元素后的逗号,写成
(param,)格式 - 多参数时按顺序写入即可,例如
(param1, param2, param3)
- 无参数时传入空元组
- 禁止手动拼接SQL字符串传入execute方法,也不需要提前将时间、数值等类型转为字符串,psycopg2的内置类型适配会自动完成类型转换,同时可以规避SQL注入风险。
内容的提问来源于stack exchange,提问作者Zaco
相关产品推荐
相关产品推荐

