2012-08-11 65 views
3

简要代码是这样的:使用Python的SQLAlchemy商店列表到SQL数据库

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来存储我的对象,我不知道要在哪里更改以达到我的目标...

回答

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

,如果你想存储chinese,你可以使用json.dumps()/json.loads()一个blob不要使用str()/eval()。使用建议的@thebjornTypeDecorator

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

+0

这与实际问题的非常好的答案无关,只是在'Word.eng'上具有'unique = True'的评论将阻止您为同形异义词存储不同的翻译(例如'live' - 韵'give'和'live' - 与'dive'押韵)。当语言A中的两个单独的概念映射到语言B中的单一概念时,例如,德语essen/fressen - >吃(取决于主题),法语知识/connaître - >知道(取决于对象),英语屋顶/天花板 - > tak [挪威语](取决于...)等。自然语言翻译很难;-) – thebjorn 2013-09-08 10:22:03

+0

@thebjorn:'单词。在这个问题中,“eng”是隐含唯一性的主要关键。不管它,我已经使用[**一对多关系](http://docs.sqlalchemy.org/en/latest/orm/relationships.html#one-to-many)而不是[** many许多**](http://docs.sqlalchemy.org/en/latest/orm/relationships.html#many-to-many)(你所描述的),以避免复杂的演示如何存储在数据库中列表。 Sqlalchemy支持它,如果你需要它。 – jfs 2013-09-08 15:51:07

0

问题是字符串化列表不能正常工作(我的结论来自您的文章) 。您可以将中文单词存储在数据库中,而不是str(word.chinese),制作u''.join(word.chinese)并以字符串形式存储数据库中的值。

4

您可以在TypeDecoratorhttp://docs.sqlalchemy.org/en/rel_0_7/core/types.html#sqlalchemy.types.TypeDecorator - 您必须创建例如列表的子类才能使其工作)中找到所需的功能。

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

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

并更改您的数据库结构以支持此操作。

0

我想你可能想要改进一点你的数据模式,而不是在你的模型属性之一中对字符串/列表进行难看的操作。

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

你的代码将显着更清洁。

eval'ing字符串只是一个非常糟糕的主意。总是。