Python用psycopg2插入PostgreSQL时datetime无法JSON序列化问题求助
嗨,我来给你几个实用的解决办法,刚好能对应你遇到的这个datetime序列化问题,而且结合PostgreSQL的场景会更合适:
解决办法
方案1:直接用psycopg2的参数化查询(强烈推荐)
其实根本不需要把字典转成JSON来插入,psycopg2本身就支持Python的datetime类型直接映射到PostgreSQL的timestamp类型,而且参数化查询还能避免SQL注入,效率也更高。
举个例子,假设你的表叫your_table,字典pDoc的键和表的列名对应,你可以这么写:
import psycopg2 from datetime import datetime # 示例字典 pDoc = { "name": "test_item", "created_at": datetime(2018, 3, 8, 10, 29, 49, 178285) } # 连接PostgreSQL数据库 conn = psycopg2.connect("dbname=your_db user=your_user password=your_pass host=your_host") cur = conn.cursor() # 构造参数化查询:列名对应字典键,用%s做占位符 columns = ', '.join(pDoc.keys()) placeholders = ', '.join(['%s'] * len(pDoc)) query = f"INSERT INTO your_table ({columns}) VALUES ({placeholders})" # 执行查询,传入字典的值列表 cur.execute(query, list(pDoc.values())) # 提交事务并关闭连接 conn.commit() cur.close() conn.close()
这样就完全绕开了JSON序列化的问题,直接让psycopg2帮你处理类型转换,省心又安全。
方案2:自定义JSON编码器(如果必须转JSON的话)
如果你因为业务需求一定要把字典转成JSON再插入,那需要自定义一个JSON编码器,把datetime对象转换成PostgreSQL能识别的ISO格式字符串。
代码示例:
import json from datetime import datetime # 自定义JSON编码器 class DateTimeEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime): # 转成ISO 8601格式字符串,PostgreSQL的json/jsonb类型可直接识别 return obj.isoformat() # 其他类型沿用默认处理逻辑 return super().default(obj) # 序列化字典 pDoc_json = json.dumps(pDoc, cls=DateTimeEncoder) # 插入到PostgreSQL的json/jsonb类型列中 cur.execute("INSERT INTO your_table (data_column) VALUES (%s)", (pDoc_json,))
之后如果需要从数据库取出这个时间,你可以用PostgreSQL的to_timestamp函数把字符串转回timestamp类型,比如:
SELECT to_timestamp(data_column->>'created_at', 'YYYY-MM-DD"T"HH24:MI:SS.US') FROM your_table;
两种方案里,方案1绝对是优先选择,不管是安全性、性能还是代码简洁性都更优。
内容的提问来源于stack exchange,提问作者Sanjay
相关产品推荐
相关产品推荐

