首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法捕获SQLAlchemy IntegrityError

无法捕获SQLAlchemy IntegrityError
EN

Stack Overflow用户
提问于 2014-07-02 11:12:58
回答 4查看 48K关注 0票数 56

尽管我可能会尝试,但我似乎不能正确地捕获sqlalchemy IntegrityError:

代码语言:javascript
复制
from sqlalchemy import exc

try:
    insert_record()
except exc.IntegrityError, exc:
    print exc # this is never called
    handle_elegantly() # this is never called

正如人们可能预期的那样:

代码语言:javascript
复制
IntegrityError: (IntegrityError) insert or update on table "my_table" 
                violates foreign key constraint "my_table_some_column_fkey"

我试着明确地说:

代码语言:javascript
复制
from sqlalchemy.exc import IntegrityError

更新:

我发现了一些似乎与这里发生的情况相吻合的东西,即在会话刷新到数据库之前以及在执行try/except块之后才抛出完整性错误:Trying to catch integrity error with SQLAlchemy

但是,在try块中添加session.flush()会生成InvalidRequestError

代码语言:javascript
复制
ERROR:root: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: (IntegrityError)
EN

回答 4

Stack Overflow用户

发布于 2016-07-05 10:21:38

我在我的Flask应用程序中也有同样的需求,我像下面这样处理它,它可以工作:

代码语言:javascript
复制
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import exc

db = SQLAlchemy(Flask(__name__))

try:
     db.session.add(resource)
     return db.session.commit()
except exc.IntegrityError:
     db.session.rollback()
票数 55
EN

Stack Overflow用户

发布于 2014-09-17 04:33:58

一旦IntegrityError被引发,无论您是否捕获到错误,您正在工作的会话都将失效。当第二条错误消息指示您To begin a new transaction with this Session, first issue Session.rollback().继续使用会话时,您需要发出一个session.rollback()

我不能确定,但我猜您或您的web框架正在尝试继续使用以某种方式引发IntegrityError的会话。我建议您在捕获异常后或在handle_elegantly函数中发出session.rollback()

如果你运行下面的代码,你就会明白我的意思:

代码语言:javascript
复制
from sqlalchemy import types
from sqlalchemy import exc
from sqlalchemy import create_engine
from sqlalchemy.schema import Column
from zope.sqlalchemy import ZopeTransactionExtension
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

Base = declarative_base()


class User(Base):
    __tablename__ = 'user'
    name = Column(types.String, primary_key=True)


def handle_elegantly(name):
    session = DBSession()
    session.add(User(name=name))
    session.flush()
    print 'Exception elegantly handled!!\n'


def pretend_view(request):
    """Pretend view in a Pyramid application using pyramid_tm"""
    session = DBSession()
    user = User()
    print '\n-------Here we rollback before continuing -------'
    try:
        session.add(user)
        session.flush()
    except exc.IntegrityError:
        session.rollback()
        handle_elegantly('This will run fine')

    print '\n------- Here we do not, and this will error -------'
    try:
        session.add(user)
        session.flush()
    except exc.IntegrityError:
        handle_elegantly('Exception will be raised')


if __name__ == '__main__':
    engine = create_engine('sqlite://')
    global DBSession
    DBSession = scoped_session(
        sessionmaker(extension=ZopeTransactionExtension()))
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    Base.metadata.create_all()
    pretend_view("dummy request")
票数 35
EN

Stack Overflow用户

发布于 2021-05-17 17:09:44

捕获错误后,必须添加session.rollback()

代码语言:javascript
复制
try:
    session.flush()
except IntegrityError:
    session.rollback()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24522290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档