我想在我的sqlite数据库中加载/保存一个dict,但是在找到一个简单的方法时遇到了一些问题.我真的不需要能够根据内容进行过滤等,因此可以简单地转换为/来自字符串.
下一个最好的东西是外键.请不要发布链接到巨大的例子,如果我盯着任何那些,我的头会爆炸.
SQLAlchemy PickleType就是为了这个.
class SomeEntity(Base): __tablename__ = 'some_entity' id = Column(Integer, primary_key=True) attributes = Column(PickleType) # Just set the attribute to save it s = SomeEntity(attributes={'baked': 'beans', 'spam': 'ham'}) session.add(s) session.commit() # If mutable=True on PickleType (the default) SQLAlchemy automatically # notices modifications. s.attributes['parrot'] = 'dead' session.commit()
您可以通过使用其他方法dumps()
和loads()
方法更改pickler来更改序列化机制.通过继承PickleType并覆盖impl attritbute的底层存储机制:
class TextPickleType(PickleType): impl = Text import json class SomeOtherEntity(Base): __tablename__ = 'some_other_entity' id = Column(Integer, primary_key=True) attributes = Column(TextPickleType(pickler=json))
您可以通过子类sqlalchemy.types.TypeDecorator
化来创建自定义类型,以处理序列化和反序列化为Text.
实现可能看起来像
import json import sqlalchemy from sqlalchemy.types import TypeDecorator SIZE = 256 class TextPickleType(TypeDecorator): impl = sqlalchemy.Text(SIZE) def process_bind_param(self, value, dialect): if value is not None: value = json.dumps(value) return value def process_result_value(self, value, dialect): if value is not None: value = json.loads(value) return value
用法示例:
class SomeModel(Base): __tablename__ = 'the_table' id = Column(Integer, primary_key=True) json_field = Column(TextPickleType()) s = SomeEntity(json_field={'baked': 'beans', 'spam': 'ham'}) session.add(s) session.commit()
SQLAlchemy文档中的示例概述了这一点,该文档还说明了如何跟踪该字典的突变.
这种方法适用于所有版本的Python,而简单地将json
值作为pickler
参数传递PickleType
将无法正常工作,正如AlexGrönholm在他对另一个答案的评论中指出的那样.