尽管我可能会尝试,但我似乎不能正确地捕获sqlalchemy IntegrityError:
from sqlalchemy import exc
try:
insert_record()
except exc.IntegrityError, exc:
print exc # this is never called
handle_elegantly() # this is never called
正如人们可能预期的那样:
IntegrityError: (IntegrityError) insert or update on table "my_table"
violates foreign key constraint "my_table_some_column_fkey"
我试着明确地说:
from sqlalchemy.exc import IntegrityError
更新:
我发现了一些似乎与这里发生的情况相吻合的东西,即在会话刷新到数据库之前以及在执行try
/except
块之后才抛出完整性错误:Trying to catch integrity error with SQLAlchemy
但是,在try
块中添加session.flush()
会生成InvalidRequestError
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)
发布于 2016-07-05 10:21:38
我在我的Flask应用程序中也有同样的需求,我像下面这样处理它,它可以工作:
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()
发布于 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()
。
如果你运行下面的代码,你就会明白我的意思:
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")
发布于 2021-05-17 17:09:44
捕获错误后,必须添加session.rollback()
:
try:
session.flush()
except IntegrityError:
session.rollback()
https://stackoverflow.com/questions/24522290
复制相似问题