python使用sqlalchemy将列表存储到sql数据库中

时间:2012-08-11 12:24:10

标签: python sqlalchemy

简短的代码是这样的:

    class Word(Base):
        __tablename__ = 'word'
        eng                 = Column(String(32),primary_key=True)
        chinese             = Column(String(128))

word = Word(eng='art',chinese=[u'艺术',u'美术'])
session.add(word)
session.commit()

我正在尝试将word.chinese存储为字符串。在python中它是一个列表...... 好吧,当我自己写sql时,我可以str(word.chinese)然后插入数据库。 当需要得到它时,我可以简单地使用eval(result)来获取原始的python对象。 但由于我使用sqlalchemy存储我的物体,我想知道在哪里改变以达到我的目标......

4 个答案:

答案 0 :(得分:7)

要在数据库中存储列表,您可以使用新表:

class Word(Base):
    __tablename__ = "words"

    id = Column(Integer, primary_key=True)
    eng = Column(String(32), unique=True)
    chinese = relationship("Chinese", backref="eng")

    def __init__(self, eng, chinese):
        self.eng = eng
        self.chinese = map(Chinese, chinese)

class Chinese(Base):
    __tablename__ = "chinese_words"

    word = Column(String(128), primary_key=True)
    eng_id = Column(Integer, ForeignKey('words.id'), primary_key=True)

    def __init__(self, word):
        self.word = word

请参阅full example

如果您想将str()存储为可以使用eval() / chinese的blob,请不要使用json.dumps() / json.loads()。使用@thebjorn TypeDecorator建议:

class Json(TypeDecorator):

    impl = String

    def process_bind_param(self, value, dialect):
        return json.dumps(value)

    def process_result_value(self, value, dialect):
        return json.loads(value)

class Word(Base):
    __tablename__ = "words"

    eng = Column(String(32), primary_key=True)
    chinese = Column(Json(128))

请参阅full example

答案 1 :(得分:4)

您会在TypeDecoratorhttp://docs.sqlalchemy.org/en/rel_0_7/core/types.html#sqlalchemy.types.TypeDecorator - 找到您要求的功能 - 您必须创建例如列表的子类才能使其正常工作。

然而,你要做的是为英语单词art存储两个不同的翻译(至少谷歌翻译告诉我:-)。将它们存储为文本字段中以逗号分隔的列表不是第一种正常形式。你应该存储两个记录

('art', u'艺术')
('art', u'美术')

并更改您的数据库结构以允许此操作。

答案 2 :(得分:0)

问题是字符串化列表不能按预期工作(我的帖子结论)。您可以将中文单词存储在数据库中,而不是str(word.chinese),make u''.join(word.chinese)并将值存储在数据库中作为字符串。

答案 3 :(得分:0)

我认为您可能想要更多地优化数据模式,而不是在模型的某个属性中对字符串/列表执行难看的操作。

我假设每个eng可以有1个或更多'中文',在这种情况下,您需要1到多个relationship和两个表/映射对象。

您的代码将更加清晰。

eval字符串只是个坏主意。总是