【问题标题】:Flask-SQLAlchemy InvalidRequestError: Object is already attached to sessionFlask-SQLAlchemy InvalidRequestError:对象已附加到会话
【发布时间】:2013-05-13 19:27:27
【问题描述】:

我正在使用 Flask 创建一个论坛项目,并使用 Flask-SQLAlchemy 管理所有用户、线程、帖子等。但是,我发现当我尝试执行 x(例如编辑帖子)时,如果我尝试执行其他任何操作(例如删除帖子),则会收到 InvalidRequestError。

用于编辑帖子,

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))

并删除帖子,

@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))

并发布帖子

@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)

不幸的是,解决这个问题的唯一可靠方法是重置实际运行应用程序的脚本 run.py

#!bin/python

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

【问题讨论】:

    标签: flask flask-sqlalchemy


    【解决方案1】:

    您是否正在使用 WooshAlchemy,因为它可能是您的问题的一部分。 Described here

    他描述了需要修改 WooshAlchemy 扩展的“修复”。

    通常,虽然这可能意味着您调用了一个 Post 模型对象,然后使用“session.add”附加它,然后尝试“session.delete”或对同一对象执行另一个“session.add”。

    此外,您的请求路由对于 Flask 来说有点奇怪,我以前从未见过 Flask 的“thr=”类型的表示法。这对你来说效果好吗?

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

    【讨论】:

    • 看起来 WhooshAlchemy 确实是问题所在。至于符号,它只是“thr=”的简写。
    • 我的意思是“thr=”部分。但我想你可以做 /thr=44/p=32/c=21 种 url 格式,我只是觉得很奇怪,仅此而已。不过,我很高兴我们发现了问题。
    • 就是这样;例如,论坛 (1) 中的特定主题 (8) 创建了 url “/forum/id=1/thr=8”。
    【解决方案2】:

    我认为您的编辑帖子没有正确完成。使用 populate_obj 函数。

    @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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 2016-03-15
      • 2021-11-27
      • 1970-01-01
      • 2018-06-08
      • 2018-01-08
      • 2019-02-08
      相关资源
      最近更新 更多