2009-04-27 7 views
3

J'ai quelques problèmes avec la mise en place de la collection de dictionnaire SQLAlchemy Python:SQLAlchemy - problème de MappedCollection

J'utilise la définition déclarative des tables. J'ai Item tableau en 1: N relation avec Record tableau. Je mis en place la relation en utilisant le code suivant:

_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') 

Maintenant, je veux travailler avec les Item s et Record s. Nous allons créer des objets:

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

Et maintenant, je veux associer ces objets en utilisant le code suivant:

i1.records['source_wav'] = r 

mais le Record r n'ont pas encore défini l'attribut name (la clé étrangère). Y a-t-il une solution pour assurer automatiquement cela? (Je sais que le réglage de la clé étrangère pendant les travaux de création Record, mais ça ne sonne pas bien pour moi).

Un grand merci

Répondre

0

Vous avez:

backref='item' 

Est-ce une faute de frappe pour

backref='name' 

?

+1

Probablement pas. Le backref est le nom d'un attribut que sqlalchemy ajoutera de l'autre côté de la relation (la classe Record), pour renvoyer à l'objet (instance d'élément) contenant la référence en aval. Donc, 'item' a un sens - dans l'exemple de honzas, r.item donne l'instance Item. –

2

Vous voulez quelque chose comme ceci:

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 

Avec cela, vous obtenez la validation souhaitée:

>>> 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

Je ne peux pas commenter, donc je vais juste écrire ce que une réponse distincte:

from sqlalchemy.orm import validates 

class Item(_Base): 
    [...] 

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

Ceci est essentiellement une copie de la réponse de Gunnlaugur mais abuser du décorateur de faire Valide quelque chose de plus utile qu'exploser.

Questions connexes