2010-02-22 5 views
16

Angenommen, ich habe 3 Klassen in SQLALchemy: Topic, Tag, Tag_To_Topic.Einfügen von Daten in viele bis viele Beziehung in SQLAlchemy

Ist es möglich, so etwas wie zu schreiben:

new_topic = Topic("new topic") 
Topics.tags = ['tag1', 'tag2', 'tag3'] 

Was ich automatisch möchte ‚tag1‘, ‚tag2‘ und ‚tag3‘ in Tag-Tabelle einzufügen, und auch das richtige Verhältnis zwischen new_topic einzusetzen und Diese 3 Tags in Tag_To_Topic Tabelle.

Bisher konnte ich aufgrund der Viele-zu-Viele-Beziehung nicht herausfinden, wie das geht. (Wenn es ein Eins-zu-Viele wäre, wäre es sehr einfach, SQLAlchemy würde es standardmäßig tun. Aber das ist viele-zu-viele.)

Ist das möglich?

Danke, Boda Cydo.

Antwort

15

Faust von allem, was Sie Ihre Viele-zu-viele-Beziehung vereinfachen könnten, indem Sie association_proxy verwenden.

Dann würde ich die Beziehung verlassen, wie es um nicht zu stören ist, was SA tut:

# here *tag_to_topic* is the relation Table object 
Topic.tags = relation('Tag', secondary=tag_to_topic) 

Und ich schlage vor, dass Sie nur eine einfache Wrapper-Eigenschaft erstellen, die den Job von dem String übersetzen Liste zu den Beziehungsobjekten (Sie werden wahrscheinlich die Beziehung umbenennen). Ihre Schlagworte Klasse würde aussehen:

class Topic(Base): 
    __tablename__ = 'topic' 
    id = Column(Integer, primary_key=True) 
    # ... other properties 

    def _find_or_create_tag(self, tag): 
     q = Tag.query.filter_by(name=tag) 
     t = q.first() 
     if not(t): 
      t = Tag(tag) 
     return t 

    def _get_tags(self): 
     return [x.name for x in self.tags] 

    def _set_tags(self, value): 
     # clear the list first 
     while self.tags: 
      del self.tags[0] 
     # add new tags 
     for tag in value: 
      self.tags.append(self._find_or_create_tag(tag)) 

    str_tags = property(_get_tags, 
         _set_tags, 
         "Property str_tags is a simple wrapper for tags relation") 

Dann soll dieser Code funktionieren:

# Test 
o = Topic() 
session.add(o) 
session.commit() 
o.str_tags = ['tag1'] 
o.str_tags = ['tag1', 'tag4'] 
session.commit() 
+0

ich das jetzt versuchen. Vielen Dank für Ihre Hilfe! – bodacydo

+0

Ich möchte Ihnen, Van, meine tiefe Dankbarkeit dafür aussprechen, dass Sie mir geholfen haben. Ihr Vorschlag, einen Assoziations-Proxy zu verwenden und die Klasse durch Hinzufügen von Hilfsmethoden zu verbessern, führte zu großartigem Code und einer großen Lösung. Vielen Dank! – bodacydo

+0

Danke, van. Aber wie man Tags "wählt", um zum Beispiel alle Themen mit den Tags "news" und o.year> 2010 zu erhalten (nur eine beliebige Eigenschaft in der Topic() - Instanz)? –