SQLAlchemy声明式中的标签字典?

6

我正在处理一个使用sqlalchemy.ext.declarative实现的庞大代码库,我需要在其中的一个类中添加类似于字典的属性。我需要的与这个问题中的相同,但是要以声明方式实现。有更多SQLAlchemy知识的人可以给我一个例子吗? 提前感谢...


如果你不需要查询属性,那么这个回答提供了一种替代方法:https://dev59.com/v3M_5IYBdhLWcg3wcCrc#1378818 - Ants Aasma
1个回答

14

声明式只是定义事物的另一种方式。实际上,你最终得到的环境与使用分离映射的环境完全相同。

既然我已经回答了另一个问题,那我也来试试这个。希望它能获得更多赞成票 ;)

好的,首先我们定义类

from sqlalchemy import Column, Integer, String, Table, create_engine
from sqlalchemy import orm, MetaData, Column, ForeignKey
from sqlalchemy.orm import relation, mapper, sessionmaker
from sqlalchemy.orm.collections import column_mapped_collection
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base(bind=engine)

class Note(Base):
    __tablename__ = 'notes'

    id_item = Column(Integer, ForeignKey('items.id'), primary_key=True)
    name = Column(String(20), primary_key=True)
    value = Column(String(100))

    def __init__(self, name, value):
        self.name = name
        self.value = value        

class Item(Base):
    __tablename__ = 'items'
    id = Column(Integer, primary_key=True)
    name = Column(String(20))
    description = Column(String(100))
    _notesdict = relation(Note, 
                          collection_class=column_mapped_collection(Note.name))
    notes = association_proxy('_notesdict', 'value', creator=Note)

    def __init__(self, name, description=''):
        self.name = name
        self.description = description

Base.metadata.create_all()

现在让我们进行一次测试:

Session = sessionmaker(bind=engine)
s = Session()

i = Item('ball', 'A round full ball')
i.notes['color'] = 'orange'
i.notes['size'] = 'big'
i.notes['data'] = 'none'

s.add(i)
s.commit()
print i.notes

我理解为:

{u'color': u'orange', u'data': u'none', u'size': u'big'}

现在让我们检查一下笔记表格...

for note in s.query(Note):
    print note.id_item, note.name, note.value

我理解为:

1 color orange
1 data none
1 size big

成功了!! :D


我遇到了 sqlalchemy.exceptions.NoReferencedTableError: Could not find table 'items' with which to generate a foreign key 错误。 - Martin Blech
修复了!必须从Note.id_item中删除ForeignKey('items.id'),并在Item声明后添加Note.__table__.append_constraint(ForeignKeyConstraint(['id_item'], ['items.id']))。还必须将Item._notesdict中的Note.name替换为Note.__table__.c.name - Martin Blech
@martin:奇怪!你使用的是哪个版本的SQLAlchemy?在我的机器上,代码完全按照上面的方式运行。 - nosklo
我刚刚确认过了,这里不需要修复。它可以正常运行。 - nosklo
@nosklo:我正在使用0.4.8版本。如果不使用我之前评论中提到的循环依赖解决方法,它将无法运行... - Martin Blech
@martin:嗯,也许就是这样。我正在使用0.5.6版本。 - nosklo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接