2017-04-02 42 views
2

什麼可能導致以下錯誤?什麼可能導致YesCon + sqlite3 ErrorConstraint SqliteException錯誤?

uncaught exception: SqliteException (SQLite3 returned ErrorConstraint while attempting to perform step.) 

奇怪的是,大多數規格的失敗,此錯誤使用withApp

但是,如果我修改wipeDBTestImport.hs

system "rm project-name_test.sqlite3*" 

然後突然所有的規格再次通過。雖然測試運行時間大約需要4-5倍,但這並不理想。

難道wipeDB邏輯(由stack new產生)不夠徹底嗎?

我想看看在models文件,看看是否我可以在那裏指定唯一性約束,但我看不出有什麼不合適的。

我曾留言的一切出來的models除外:

User 
    emailAddress Text 
    password ByteString 
    verified Bool 
    verifyKey Text 
    resetPasswordKey Text 
    deriving Show 

Foo 
    userA UserId 
    userB UserId 
    deriving Show 

如果有限制,他們將在這個文件中,就不是嗎?還是可以有其他地方宣佈約束?無論如何,這個例外可能涉及哪些限制?

我還沒有儘可能縮小它的範圍,但似乎所有這些都可以追溯到runDB $ insert $ Foo,如果我刪除了,那麼有問題的異常消失了,更多的規範會通過,並且只有少數人失敗,因爲他們期望插入已經發生。而且他們也失敗了斷言失敗,而不是ErrorConstraint異常。

如果這個錯誤有多種可能的原因,我想聽聽他們,因爲我發現這個例外比我想要的更加模糊。

+1

我在這裏開了這個問題:https://github.com/yesodweb/persistent/issues/675 – Wizek

回答

2

This是我找到的最佳解決方案。看起來會是「官方」解決方案。

所以在我的項目中我做了this way

所以這就是我現在的wipeDB功能:

wipeDB :: App -> IO() 
wipeDB app = do 
    let settings = appSettings app 
     logFunc = messageLoggerSource app (appLogger app) 

    sqliteConn <- rawConnection (sqlDatabase $ appDatabaseConf settings) 
    let infoNoFK = set fkEnabled False $ mkSqliteConnectionInfo "" 
     wrapper = wrapConnectionInfo infoNoFK sqliteConn 
    pool <- runLoggingT (createSqlPool wrapper 1) logFunc 

    flip runSqlPersistMPool pool $ do 
     tables <- getTables 
     sqlBackend <- ask 
     let queries = map (\t -> "DELETE FROM " ++ (connEscapeName sqlBackend $ DBName t)) tables 
     forM_ queries (\q -> rawExecute q []) 
相關問題