使用SQLAlchemy存储含列表的Python字典到PostgreSQL HSTORE报错如何解决
报错核心原因
该错误不是SQLAlchemy配置遗漏导致,本质是PostgreSQL HSTORE类型的原生限制:
- HSTORE是扁平化的键值对存储结构,强制要求所有键和值都只能是普通字符串类型,不支持数组、数值、嵌套字典等非字符串值,因此你传入列表作为值时会触发类型校验错误。
- 你提供的插入代码存在笔误:
db.Session.add(scan)应修改为db.Session.add(data),不过该笔误不是本次报错的核心诱因。
解决方案
方案1:保留HSTORE类型,序列化非字符串值
如果必须使用HSTORE的特有能力,可以在写入前将列表等非字符串值序列化为JSON字符串,读取时再反序列化即可:
import json # 写入时序列化 data = Data( id='fancy_id', data={ 'foo': json.dumps(['bar', 'bar']) }, ) db.Session.add(data) db.Session.commit() # 读取时反序列化 res = db.Session.get(Data, 'fancy_id') foo_list = json.loads(res.data['foo'])
方案2:更换字段类型为JSONB(更推荐)
如果没有强制使用HSTORE的需求,优先选择PostgreSQL原生的JSONB类型,原生支持列表、数值、嵌套字典等复杂结构,不需要额外序列化处理:
首先修改表字段定义:
from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy import Column, String from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Data(Base): id = Column(String, primary_key=True) data = Column(JSONB) # 替换原HSTORE类型
修改后直接写入带列表的字典即可正常执行:
data = Data( id='fancy_id', data={ 'foo': ['bar', 'bar'] }, ) db.Session.add(data) db.Session.commit()
内容的提问来源于stack exchange,提问作者zkdev
相关产品推荐
相关产品推荐

