我对烧瓶和 sqlalchemy 完全陌生。我尝试制作一个网站只是为了更好地了解烧瓶。我有类似博客的东西,用户可以在其中创建帖子并设置多个标签。我使用烧瓶-sqlalchemy 和 wtforms-alchemy。我有 2 个模型
association_table = db.Table('association',
db.Column('post_id', db.Integer, db.ForeignKey('post.id')),
db.Column('category_id', db.Integer, db.ForeignKey('category.id'))
)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), nullable=False)
body = db.Column(db.Text, nullable=False)
pub_date = db.Column(db.DateTime)
categories = db.relationship('Category', secondary=association_table,
backref=db.backref('posts', lazy='dynamic'))
...
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
...
我可以使用下一个视图创建新帖子
def add():
form = PostForm(request.form)
if request.method == 'POST' and form.validate():
post = Post(form.title.data, form.body.data)
db.session.add(post)
tags = form.tags.data.split(',')
for tag in tags:
category = Category.query.filter_by(name=tag.strip()).first()
if not category:
category = Category(tag.strip())
post.categories.append(category)
db.session.commit()
return redirect(...)
return render_template(...)
这可以正常工作。但是我在编辑帖子时遇到了一些问题。当我更改标题或正文时,我必须使用 db.session.merge(post) 否则它不想将更改保存在数据库中。但是在所有教程中都没有那种合并方法。第二个问题是我无法更新帖子的标签。我可以创建一个新标签并将其添加到某个帖子中。但是,如果我尝试将现有标签添加到任何帖子中,则会出现错误。
AssertionError: A conflicting state is already present in the identity map for key (<class 'db.models.Category'>, (1,))
我的观点看起来像
def edit(post_id):
post = Post.query.get(post_id)
form = PostForm(request.form, post)
if request.method == 'POST' and form.validate():
...
tags = form.tags.data.split(',')
for tag in tags:
category = Category.query.filter_by(name=tag.strip()).first()
if not category:
category = Category(tag.strip())
db.session.remove()
post.categories.append(category)
form.populate_obj(post)
db.session.merge(post)
db.session.commit()
return redirect(...)
else:
...
return render_template(...)
另外,如果我不使用 db.session.remove() 我会收到另一个错误
InvalidRequestError: Object '<Category at 0x7f9de40c0d90>' is already attached to session '6' (this is '1')
我哪里错了?谢谢你的帮助!
一次更新。只是为了测试。如果我从一篇文章中迭代标签列表,我可以删除这些标签并将其附加回来。
tags = list(post.categories)
for tag in tags:
post.categories.remove(tag)
for tag in tags:
post.categories.append(tag)
但是如果我删除标签然后从数据库中获取标签并尝试追加 - 得到一个错误
tags = list(post.categories)
for tag in tags:
post.categories.remove(tag)
for tag in tags:
category = Category.query.filter_by(name=tag.name).first()
post.categories.append(tag)
AssertionError: A conflicting state is already present in the identity map for key (<class 'db.models.Category'>, (1,))
我很困惑