Как удалить записи из таблицы "многие ко многим" (вторичной) в SQLAlchemy?

у меня возникли проблемы с удалением записей из PostTag таблицу, содержащую Post и . Это моя таблица отношений:

tags = db.Table('PostTag',
    db.Column('Tag', db.Integer, db.ForeignKey('Tag.Id')),
    db.Column('Post', db.Integer, db.ForeignKey('Post.Id'))
)

и

tags = db.relationship(Tag, secondary=tags, backref=db.backref('Post', lazy='dynamic'))

когда я делаю это:

from models.Post import Post

posts = Post.query.join(Post.tags).filter(Post.Id == id).all()
if(posts):
   return posts
return False

а то

for posttag in post[0].tags:
    db.session.delete(posttag)
    db.session.flush()

строки из отношения "многие ко многим" удаляются, но также и записи из Tag таблица.

мне нужно удалить записи из PostTag таблица для некоторого условия (Post=1 для пример)

я искал в интернете но я не нашел ничего убедительного. Мне не нужны отношения "многие ко многим".

это журнал sql:

 297 Query  DELETE FROM `PostTag` WHERE `PostTag`.`Tag` = 14 AND `PostTag`.`Post` = 3
 297 Query  DELETE FROM `PostTag` WHERE `PostTag`.`Tag` = 14 AND `PostTag`.`Post` = 18
 297 Query  DELETE FROM `Tag` WHERE `Tag`.`Id` = 14

последние строки 297 Query DELETE FROMTagWHERETag.Id= 14 там не должно быть.

обновление / возможно решение

я решил это с помощью:

sql = 'DELETE FROM PostTag WHERE Post=%s'
db.engine.execute(sql, post, ())

но это не просто путь Орма. То же самое касается insert. Я постараюсь получить это решенный путь ORM. Я отправлю ответ, если я решить эту проблему.

2 ответов


попробуйте это:

post = db.session.query(Post).get(1)
post.tags = []
db.session.commit()

здесь мы переопределяем коллекцию post.tags к пустому массиву и фиксации изменений. Чтобы объяснить это, я буду ссылаться на SQLAlchemy docs:

коллекции в SQLAlchemy прозрачно инструментируются. Инструментирование означает, что обычные операции над коллекцией отслеживаются и приводят к записи изменений в базу данных во время flush.

так SQLAlchemy отслеживает изменения, которые мы вносим в пост сбора.теги и обновляет его при фиксации.

если бы у нас был только один тег (скажем sometag) мы можем использовать remove способ такой:

post = db.session.query(Post).get(1)
post.tags.remove(sometag)
db.session.commit()

попытке удалить объекты из коллекции:

post[0].tags.clear()

вы также можете удалить отдельные элементы:

post[0].tags.remove(posttag)