2009-04-27 8 views
3

Ich habe einige Probleme mit der Einstellung die Wörterbuchsammlung in Python SQLAlchemy up:SQLAlchemy - MappedCollection Problem

ich deklarative Definition von Tabellen verwenden. Ich habe Item Tabelle in 1: N Beziehung mit Record Tabelle. Ich habe die Beziehung mit dem folgenden Code auf:

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

Jetzt habe ich mit den Item s und Record s arbeiten möchten. Lassen Sie uns einige Objekte erstellen:

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

Und nun möchte ich diese Objekte assoziieren mit dem folgenden Code:

i1.records['source_wav'] = r 

aber die Record r nicht die name Attribut gesetzt haben (der Fremdschlüssel). Gibt es eine Lösung, wie dies automatisch sichergestellt werden kann? (Ich weiß, dass die Einstellung des Fremdschlüssels während der Record Erstellung funktioniert, aber es klingt nicht gut für mich).

Vielen Dank

Antwort

0

Sie haben:

backref='item' 

Ist das ein Tippfehler für

backref='name' 

?

+1

Wahrscheinlich nicht. Der Backref ist der Name eines Attributs, das sqlalchemy der anderen Seite der Relation (der Record-Klasse) hinzufügt, um auf das Objekt (Item-Instanz) zurückzugreifen, das die Vorwärtsreferenz enthält. Also macht 'item' Sinn - im Beispiel von honzas liefert r.item die Item-Instanz. –

2

Sie wollen etwas wie folgt aus:

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 

Damit Sie die gewünschte Bestätigung erhalten:

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

Ich kann noch nicht kommentieren, so dass ich nur diese gehen zu schreiben, wie eine separate Antwort:

from sqlalchemy.orm import validates 

class Item(_Base): 
    [...] 

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

Dies ist im Grunde eine Kopie von Gunnlaugur Antwort, aber die validates Dekorateur missbrauchen zu tun etwas nützlicheres als explodieren.