Как удалить записи из таблицы "многие ко многим" (вторичной) в 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 FROM
TagWHERE
Tag.
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)