首页 > sqlalchemy.exc.InvalidRequestError

sqlalchemy.exc.InvalidRequestError

一个github上的项目
项目地址

项目正常启动,但在添加文章的时候报:

sqlalchemy.exc.InvalidRequestError
InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: 'NoneType' object has no attribute '_sa_instance_state'

model.py内容:

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    email = db.Column(db.String)
    password = db.Column(db.String)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    posts = db.relationship('Post', backref='author')
    comments = db.relationship('Comment', backref='author')

    locale = db.Column(db.String, default='zh')

    @staticmethod
    def on_created(target, value, oldvalue, initiator):
        target.role = Role.query.filter_by(name='Guests').first()


class AnonymousUser(AnonymousUserMixin):
    @property
    def locale(self):
        return 'zh'

    def is_administrator(self):
        return False


login_manager.anonymous_user = AnonymousUser


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


db.event.listen(User.name, 'set', User.on_created)


class Post(db.Model):
    __tablename__ = 'posts'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    body = db.Column(db.String)
    body_html = db.Column(db.String)
    created = db.Column(db.DateTime, index=True, default=datetime.utcnow)

    comments = db.relationship('Comment', backref='post')
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    @staticmethod
    def on_body_changed(target, value, oldvalue, initiator):
        if value is None or (value is ''):
            target.body_html = ''
        else:
            target.body_html = markdown(value)


db.event.listen(Post.body, 'set', Post.on_body_changed)

viwe.py内容

@main.route('/edit', methods=['GET', 'POST'])
@main.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit(id=0):
    form = PostForm()

    if id == 0:
        post = Post(author=current_user)
    else:
        post = Post.query.get_or_404(id)

    if form.validate_on_submit():
        post.body = form.body.data
        post.title = form.title.data

        db.session.add(post)
        db.session.commit()
        return redirect(url_for('.post', id=post.id))

    form.title.data = post.title
    form.body.data = post.body

    title = _(u'添加新文章')
    if id > 0:
        title = _(u'编辑 - %(title)', title=post.title)

    return render_template('posts/edit.html',
                           title=title,
                           form=form,
                           post=post)


点击发表文章的时候就出现这问题,不知道问题在哪。


在views.py里面:
post = Post(author=current_user)
修改为:
post =Post(author_id=current_user.id)
就可以了。
Post()括号里面给的是查询条件值,而不是类,你可以分别打印出current_user & current_user.id的内容看看。


主要原因是在写入会话的过程中发生了错误,导致会话失效,出现了这种情况应该回滚数据库会话。
首先的提交数据的地方有错误,需要检查一下,因为看不出你的代码需要做什么,所以不能帮你检查了。
可以这样用

try:
    <use session>
    session.commit()
except:
   session.rollback()
   raise
finally:
   session.close()

一旦会话出错,就回滚数据库会话
可以参考sqlalchemy的官方文档
http://sqlalchemy.readthedocs.io/en/latest/faq/sessions.html?highlight=previous%20flush#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar

【热门文章】
【热门文章】