Подтвердить что ты не робот

Вставка данных во многих отношениях в SQLAlchemy

Предположим, что у меня есть 3 класса в SQLALchemy: Topic, Tag, Tag_To_Topic.

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

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

Который я хотел бы автоматически вставить теги1, tag2 и tag3 в таблицу тегов, а также вставить правильную связь между new_topic и этими тэгами в таблице Tag_To_Topic.

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

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

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

4b9b3361

Ответ 1

Кулак всего, что вы могли бы упростить отношение "многие ко многим", используя 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()