我完全用flask和sqlalchemy創建新的。我試圖製作一個網站,以便更好地理解燒瓶。我有類似博客的地方,用戶可以創建帖子並設置多個標籤。我用flask-sqlalchemy和wtforms-alchemy。我有2種型號無法更新Flask中的多對多關係條目
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,))
我很困惑
是的,這是使用flask_whooshalchemy庫時的一個問題。 Miguel Grinberg的補丁(上面答案中的鏈接)最終被合併到庫的github存儲庫中。但截至2014年5月尚未發佈。如果您需要通過此錯誤,您需要手動將修補程序應用於flask_whooshalchemy.py。 – Will