我想在我的sqlite数据库中加载/保存一个字典,但是在找出一个简单的方法时遇到了一些问题。我真的不需要能够根据内容进行过滤等,因此可以简单地转换为/来自字符串。
下一个最好的东西是外键。请不要发布链接到大量的例子,如果我盯着任何那些,我的头会爆炸。
答案 0 :(得分:56)
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))
答案 1 :(得分:12)
您可以通过继承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()
这在an example in the SQLAlchemy docs中有概述,其中还展示了如何跟踪该词典的突变。
这种方法适用于所有版本的Python,而只是将json
作为pickler
PickleType
https://i.stack.imgur.com/97vxd.jpg
https://i.stack.imgur.com/M3WyL.jpg
参数的值传递将无法正常工作,如AlexGrönholm points out所示他对另一个答案的评论。
答案 2 :(得分:3)
如果您需要映射1-N 关系并将其映射为dict
而不是list
,请阅读Dictionary Based Collections
但是如果你的意思是字段,那么你可以做些什么来创建一个字符串类型的数据库字段,它被映射到你的Python对象。但是在同一个python对象上,你提供了一个属性,它将是这个dict()类型的映射字符串字段的代理。 代码示例(未测试):
class MyObject(object):
# fields (mapped automatically by sqlalchemy using mapper(...)
MyFieldAsString = None
def _get_MyFieldAsDict(self):
if self.MyFieldAsString:
return eval(self.MyFieldAsString)
else:
return {} # be careful with None and empty dict
def _set_MyFieldAsDict(self, value):
if value:
self.MyFieldAsString = str(value)
else:
self.MyFieldAsString = None
MyFieldAsDict = property(_get_MyFieldAsDict, _set_MyFieldAsDict)
答案 3 :(得分:2)
SQLAlchemy 有一个你可以使用的内置 JSON 类型:
attributes = Column(JSON)