2009-04-27 48 views
3

我有一些问题在Python的SQLAlchemy的设立字典集合:SQLAlchemy的 - MappedCollection问题

我使用表的声明性定义。我有Item表与1:N关系表Record表。我建立的关系用下面的代码:

_Base = declarative_base() 

class Record(_Base): 
    __tablename__ = 'records' 

    item_id = Column(String(M_ITEM_ID), ForeignKey('items.id')) 
    id = Column(String(M_RECORD_ID), primary_key=True) 
    uri = Column(String(M_RECORD_URI)) 
    name = Column(String(M_RECORD_NAME)) 

class Item(_Base): 
    __tablename__ = 'items' 

    id = Column(String(M_ITEM_ID), primary_key=True) 

    records = relation(Record, collection_class=column_mapped_collection(Record.name), backref='item') 

现在我想用Item S和Record s到工作。让我们来创建一些对象:

i1 = Item(id='id1') 
r = Record(id='mujrecord') 

,现在我想对这些对象的使用下面的代码相关联:

i1.records['source_wav'] = r 

Record r没有固定的name属性(外键)。有没有解决方案如何自动确保这一点? (我知道在Record创作过程中设置外键,但对我来说听起来不太好)。

非常感谢

回答

0

您有:

backref='item' 

这是对

backref='name' 

一个错字?

+1

可能不是。 backref是sqlalchemy将添加到关系的另一端(Record类)的属性的名称,以引用返回包含前向引用的对象(Item实例)。所以'item'是有道理的 - 在honzas的例子中,r.item产生Item实例。 – 2009-05-19 20:03:52

2

你想是这样的:

from sqlalchemy.orm import validates 

class Item(_Base): 
    [...] 

    @validates('records') 
    def validate_record(self, key, record): 
     assert record.name is not None, "Record fails validation, must have a name" 
     return record 

有了这个,你得到想要的验证:

>>> i1 = Item(id='id1') 
>>> r = Record(id='mujrecord') 
>>> i1.records['source_wav'] = r 
Traceback (most recent call last): 
    [...] 
AssertionError: Record fails validation, must have a name 
>>> r.name = 'foo' 
>>> i1.records['source_wav'] = r 
>>> 
1

我不能评论,所以我只是去写为一个单独的答案:

from sqlalchemy.orm import validates 

class Item(_Base): 
    [...] 

    @validates('records') 
    def validate_record(self, key, record): 
     record.name=key 
     return record 

这基本上是Gunnlaugur的答案的副本,但滥用验证装饰器做比爆炸更有用的东西。