Python在sqlalchemy中进行了解释

时间:2009-09-04 10:03:37

标签: python sql sqlite sqlalchemy

我想在我的sqlite数据库中加载/保存一个字典,但是在找出一个简单的方法时遇到了一些问题。我真的不需要能够根据内容进行过滤等,因此可以简单地转换为/来自字符串。

下一个最好的东西是外键。请不要发布链接到大量的例子,如果我盯着任何那些,我的头会爆炸。

4 个答案:

答案 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)