16

嘗試,因爲我可能,我似乎無法正確地捕捉SQLAlchemy的IntegrityError:不能趕上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 

UPDATE:

我發現一些看起來很適合這裏發生了什麼,在那裏完整性沒有引發錯誤,直到會話被刷新到數據庫,並經過try/except段已執行:Trying to catch integrity error with SQLAlchemy

但是,添加session.flush()try塊產生一個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) 
+0

是你100%這是它發生的地方? –

+0

你正在使用哪個數據庫? – alecxe

+0

此外,是否將'IntegrityError'更改爲'DatabaseError'幫助?謝謝。 – alecxe

回答

14

只要IntegrityError提高,不管你是否已經抓到了錯誤,你在使用的會話無效。由於第二條錯誤消息指示您繼續使用會話,因此您需要發出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") 
9

我在我的應用瓶同樣需要,我處理它象下面和它的作品:

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 as e: 
    db.session().rollback() 
+0

謝謝,我試圖使用'exc.InterityError'沒有從sqlalchemy第一次導入它 –