Flask-SQLAlchemy InvalidRequestError: Object is already attached to session

孤者浪人 提交于 2019-12-12 10:54:43

问题


I'm creating a forum project using Flask, and managing all the users, threads, posts, etc. using Flask-SQLAlchemy. However, I've found that when I attempt to do x (e.g. edit a post), I get an InvalidRequestError if I attempt to do anything else (e.g. delete the post).

For editing a post,

def post_edit(id, t_id, p_id):
  post = Post.query.filter_by(id=p_id).first()
  if post.author.username == g.user.username:
    form = PostForm(body=post.body)
    if form.validate_on_submit():
      post.body = form.body.data
      db.session.commit()
      return redirect(url_for('thread', id=id, t_id=t_id))
    return render_template('post_edit.html', form=form, title='Edit')
  else:
    flash('Access denied.')
    return redirect(url_for('thread', id=id, t_id=t_id))

and deleting a post,

@app.route('/forum=<id>/thr=<t_id>/p=<p_id>/delete', methods=['GET','POST'])
def post_delete(id, t_id, p_id):
  post = Post.query.filter_by(id=p_id).first()
  if post.author.username == g.user.username:
    db.session.delete(post)
    db.session.commit()
    return redirect(url_for('thread', id=id, t_id=t_id))
  else:
    flash('Access denied.')
    return redirect(url_for('thread', id=id, t_id=t_id))

and posting a post

@app.route('/forum/id=<id>/thr=<t_id>', methods=['GET','POST'])
def thread(id, t_id):
  forum = Forum.query.filter_by(id=id).first()
  thread = Thread.query.filter_by(id=t_id).first()
  posts = Post.query.filter_by(thread=thread).all()
  form = PostForm()
  if form.validate_on_submit():
    post = Post(body=form.body.data,
                timestamp=datetime.utcnow(),
                thread=thread,
                author=g.user)
    db.session.add(post)
    db.session.commit()
    return redirect(url_for('thread', id=id, t_id=t_id))
  return render_template('thread.html', forum=forum, thread=thread, posts=posts, form=form, title=thread.title)

Unfortunately, the only surefire way to make this problem resolve itself is to reset the script that actually runs the app, run.py

#!bin/python

from app import app
app.run(debug=True,host='0.0.0.0')

回答1:


Are you using WooshAlchemy because it might be part of your problem. Described here

He describes the "fix" that requires modification of WooshAlchemy extension.

Usually though it could mean you called a Post model object and then attached it using "session.add" and then tried to "session.delete" or did another "session.add" on the same object.

Also your request routing is a bit strange for flask I've never seen the "thr=<t_id>" type of notation with Flask before. Has that been working well for you?

http://flask.pocoo.org/docs/quickstart/#variable-rules




回答2:


I think your edit post is not done correctly. Use the populate_obj function.

@app.route('/forum=<id>/thr=<t_id>/p=<p_id>/edit', methods=['GET','POST'])
def post_edit(id, t_id, p_id):
    post = Post.query.filter_by(id=p_id).first()
    if post.author.username == g.user.username:
        form = PostForm(obj=post)
        if form.validate_on_submit():
            form.populate_obj(post)
            db.session.commit()
            return redirect(url_for('thread', id=id, t_id=t_id))
        return render_template('post_edit.html', form=form, title='Edit')
   else:
       flash('Access denied.')
       return redirect(url_for('thread', id=id, t_id=t_id))


来源:https://stackoverflow.com/questions/16529660/flask-sqlalchemy-invalidrequesterror-object-is-already-attached-to-session

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!