私はフラスコとsqlalchemyをまったく使用していません。フラスコをよりよく理解するためだけに、1 つの Web サイトを作成しようとしています。ユーザーが投稿を作成して複数のタグを設定できるブログのようなものがあります。私はフラスコ 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) を使用する必要があります。そうしないと、データベースに変更を保存したくありません。しかし、すべてのチュートリアルでそのマージ方法はありません。2 つ目の問題は、投稿のタグを更新できないことです。新しいタグを作成して、投稿に追加できます。しかし、既存のタグを投稿に追加しようとすると、エラーが発生します。
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')
どこが間違っていますか?助けてくれてありがとう!
1 つの更新。テスト用です。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,))
私は混乱しています