Вставка данных в отношение «многие ко многим» в SQLAlchemy - PullRequest
17 голосов
/ 22 февраля 2010

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

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

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

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

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

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

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

1 Ответ

17 голосов
/ 22 февраля 2010

Во-первых, вы можете упростить ваше отношение многие ко многим, используя 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...