2010-02-22 5 views
16

Предположим, у меня есть 3 класса в SQLALchemy: Topic, Tag, Tag_To_Topic.Вставка данных во многих отношениях в SQLAlchemy

Можно ли написать что-то вроде:

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

который я хотел бы, чтобы автоматически вставить «tag1», «tag2» и «Tag3» в таблице тегов, а также вставить правильное соотношение между new_topic и эти 3 тега в таблице Tag_To_Topic.

До сих пор я не мог понять, как это сделать из-за отношений «многие ко многим». (Если бы это было один-ко-многим, это было бы очень просто, SQLAlchemy будет делать это по умолчанию уже, но это много-ко-многим.)

Возможно ли это?

Спасибо, Бода Cydo.

ответ

15

Кулак всего, что вы могли бы упростить для своего отношения многие-ко-многим, используя association_proxy.

Тогда я оставил бы отношение, как это делается для того, чтобы не мешать, что делает SA:

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

И я полагаю, что вы просто создать простое свойство-обертку, которая делает работу по переводу строки список объектов отношения (вы, вероятно, переименуете отношение). Ваш Метки класс будет выглядеть так:

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

Тогда этот код должен работать:

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

Я пытаюсь это сейчас. Огромное спасибо за помощь! – bodacydo

+0

Я хотел бы выразить вам свою глубокую благодарность, Ван, за помощь. Ваше предложение об использовании прокси-сервера ассоциации и улучшении класса путем добавления вспомогательных методов привело к большому коду и решению. Благодаря! – bodacydo

+0

Спасибо, фургон. Но как «выбрать» теги, например, получить все темы с тегами «news» и o.year> 2010 (просто произвольное свойство в экземпляре Topic())? –

Смежные вопросы