Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-SQLAlchemy InvalidRequestError: Object is already attached to session

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')
like image 892
Ganye Avatar asked Oct 21 '22 10:10

Ganye


1 Answers

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

like image 154
Dexter Avatar answered Oct 25 '22 20:10

Dexter