2009-09-09 4 views
6

Ich arbeite an einer ziemlich großen Codebasis, die mit sqlalchemy.ext.declarative implementiert wurde, und ich muss eine dict-ähnliche Eigenschaft zu einer der Klassen hinzufügen. Was ich brauche ist das gleiche wie in this question, aber in einer deklarativen Art und Weise. Kann jemand mit mehr Wissen in SQLAlchemy mir ein Beispiel geben? Vielen Dank im Voraus ...Wörterbuch der Tags in deklarativen SQLAlchemy?

+0

Wenn Sie nicht über die Eigenschaft abfragen müssen, bietet diese Antwort einen alternativen Ansatz: http://stackoverflow.com/questions/1378325/python-dicts-in-sqlalchemy/1378818#1378818 –

Antwort

13

Deklarativ ist nur eine andere Art, Dinge zu definieren. Praktisch erhalten Sie die exakt gleiche Umgebung, als wenn Sie getrennte Zuordnung verwenden würden.

Da ich die andere Frage beantwortet habe, werde ich dieses auch versuchen. Hoffe, dass es mehr upvotes gibt;)

Nun, zunächst definieren wir die Klassen

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

Nun wollen wir machen einen Test:

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 

ich:

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

Nun lasst uns Überprüfen Sie die Notizen Tabelle ...

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

ich:

1 color orange 
1 data none 
1 size big 

Es funktioniert !! : D

+0

danke @nosklo! –

+0

Ich erhalte eine 'sqlalchemy.exceptions.NoReferencedTableError: Konnte Tabellen 'Elemente' nicht finden, mit denen ein Fremdschlüssel zu erzeugen ' –

+0

behoben! Musste 'ForeignKey ('items.id')' aus 'Note.id_item' entfernen und' Note .__ Tabelle __. Append_constraint (ForeignKeyConstraint (['id_item'], ['items.id'])) '' nach der Deklaration von "Gegenstand". Außerdem musste "Note.name" durch "Note .__ Tabelle __. C.name" in "Item._notesdict" ersetzt werden. –