2012-07-26 25 views
8

我想處理的情況下,有一個主鍵或唯一的鍵衝突,又名重複的條目。爲此我抓住了IntegrityError,這很好地捕捉到了錯誤。問題是,我似乎無法找到任何簡單的錯誤消息或錯誤代碼來檢查。所有我得到的是IntegrityError.message屬性,它是一個字符串,它看起來像這樣:(「關鍵‘名稱’重複條目‘foobar的’」 1062)SQLAlchemy錯誤處理 - 它是如何完成的?

(IntegrityError)

這不是很有幫助。使用它,我將不得不開始解析他們的代碼和消息的錯誤消息。除了上調用dir僅顯示以下屬性:

'ARGS', 'connection_invalidated', '實例', '信息', '原稿', 'PARAMS', '聲明'

args只是一個帶有上述字符串的單項元組,而params是我試圖插入的數據。我似乎無法找到任何方式來確定這實際上是一個重複的關鍵錯誤,而不必開始使用正則表達式或其他東西來解析錯誤消息。

任何人都可以解釋一下這個問題?

感謝

回答

12

,同時通過更仔細地閱讀文檔寫的問題,我想通了這一點。我仍然會發布這個,因爲它可能對某人有所幫助。

在SQLAlchemy的DBAPIError,從該IntegrityError是子類的文檔,它解釋該異常僅僅是用於底層數據庫API錯誤的包裝和原始誤差保存爲在異常orig。果然,打電話e.orig.args我得到一個很好的有組織的元組:

(1062,「關鍵‘名稱’重複條目‘foobar的’」)

+0

是的,這是非常有幫助的。 Thx爲我節省了挖掘時間。 – 2016-02-17 19:48:30

0

據我所知,唯一的辦法就是解析異常中的錯誤字符串。我找不到指定錯誤的任何元組,唯一違反唯一性約束和值的列。

具體而言,可以使用子字符串搜索運算符或正則表達式搜索異常消息。例如:

db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user)) 
    try: 
     db.session.commit() 
    except IntegrityError as err: 
     db.session.rollback() 
     if "UNIQUE constraint failed: user.username" in str(err): 
      return False, "error, username already exists (%s)" % username 
     elif "FOREIGN KEY constraint failed" in str(err): 
      return False, "supplier does not exist" 
     else: 
      return False, "unknown error adding user" 

然而,這些字符串可能會很長,因爲SQL語句包括,例如:

(sqlite3.IntegrityError) UNIQUE constraint failed: user.username [SQL: 'INSERT INTO user (username, password_hash, created_time, creator_id, role, is_active, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?)'] [parameters: ('bob', ... 

因此,你將盡量減少錯誤處理延遲解析例外,如果你通過搜索數據庫錯誤消息,沒有sqlalchemy添加的信息。這可以通過檢查錯誤來完成。ARGS,這應該是更小:

'(sqlite3.IntegrityError) UNIQUE constraint failed: supplier_user.username',) 

更新例如:

db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user)) 
    try: 
     db.session.commit() 
    except IntegrityError as err: 
     db.session.rollback() 
     err_msg = err.args[0] 
     if "UNIQUE constraint failed: supplier_user.username" in err_msg: 
      return False, "error, supplier username already exists (%s)" % username 
     elif "FOREIGN KEY constraint failed" in err_msg: 
      return False, "supplier does not exist" 
     else: 
      return False, "unknown error adding user" 

注意我這裏使用的錯誤語法是sqlite3的。解析mysql異常錯誤消息,如:

(1062, "Duplicate entry 'usr544' for key 'username'") 

可以用適當的正則表達式完成。請注意,它看起來像一個元組,但它實際上是一個字符串(sqlalchemy版本1.1.3和mysql 5.5)。

例如:

except IntegrityError as err: 
     db.session.rollback() 
     if re.match("(.*)Duplicate entry(.*)for key 'username'(.*)", err.args[0]): 
    .... etc ....