如何从SQLAlchemy中的多对多(辅助)表中删除记录?

pre*_*tch 11 python sqlalchemy

我在从PostTag包含PostTag列的表中删除记录时遇到问题.这是我的关系表:

tags = db.Table('PostTag',
    db.Column('Tag', db.Integer, db.ForeignKey('Tag.Id')),
    db.Column('Post', db.Integer, db.ForeignKey('Post.Id'))
)
Run Code Online (Sandbox Code Playgroud)

tags = db.relationship(Tag, secondary=tags, backref=db.backref('Post', lazy='dynamic'))
Run Code Online (Sandbox Code Playgroud)

当我这样做:

from models.Post import Post

posts = Post.query.join(Post.tags).filter(Post.Id == id).all()
if(posts):
   return posts
return False
Run Code Online (Sandbox Code Playgroud)

然后

for posttag in post[0].tags:
    db.session.delete(posttag)
    db.session.flush()
Run Code Online (Sandbox Code Playgroud)

删除多对多关系的行,但也删除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
Run Code Online (Sandbox Code Playgroud)

最后一行297 Query DELETE FROM标记WHERE标记.ID = 14不应该存在.

更新/可能解决方案

我解决了这个问题:

sql = 'DELETE FROM PostTag WHERE Post=%s'
db.engine.execute(sql, post, ())
Run Code Online (Sandbox Code Playgroud)

但这不仅仅是ORM的方式.插入也一样.我会尽力让这个解决ORM方式.如果我让这个问题消失,我会发回答.

psp*_*cer 18

试试这个:

post = db.session.query(Post).get(1)
post.tags = []
db.session.commit()
Run Code Online (Sandbox Code Playgroud)

在这里,我们将集合重新定义为post.tags空数组并提交更改.为了解释这一点,我将参考SQLAlchemy文档:

SQLAlchemy中的集合是透明的工具.检测意味着跟踪对集合的正常操作,并导致在刷新时将更改写入数据库.

因此,SQLAlchemy会跟踪我们对集合post.tags所做的更改,并在提交时对其进行更新.

如果我们只有一个标签(比方说sometag)我们可以使用这样的remove方法:

post = db.session.query(Post).get(1)
post.tags.remove(sometag)
db.session.commit()
Run Code Online (Sandbox Code Playgroud)


Ada*_*tek 6

尝试从集合中删除对象:

post[0].tags.clear()
Run Code Online (Sandbox Code Playgroud)

您还可以删除单个项目:

post[0].tags.remove(posttag)
Run Code Online (Sandbox Code Playgroud)

  • “post[0].tags.clear()”——这对我不起作用。我得到以下信息: AttributeError: 'InstrumentedList' object has no attribute 'clear' (2认同)