samedi 21 mars 2015

PersistMarshalError reading from sqlite

I'm trying to read from an existing SQLite database using persistent-sql.


I'm getting a PersistMarshalError, and I suspect it might be a bug in the sqlite driver interpreting the sqlite output ... but would love to be wrong :)


This is the schema:



CREATE TABLE "System" (
'SystemId' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
'SystemName' TEXT(255) COLLATE NOCASE,
'SystemX' Double,
'SystemY' Double,
'SystemZ' Double,
'SystemSize' Double
);


And this is the haskell test code:



{-# LANGUAGE QuasiQuotes, TypeFamilies, GeneralizedNewtypeDeriving, TemplateHaskell,
OverloadedStrings, GADTs, FlexibleContexts, ScopedTypeVariables #-}
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import Control.Monad.IO.Class (liftIO)
import Data.Time (UTCTime)
import Data.Text (Text)
import Control.Monad.Logger
import Control.Monad.Trans.Resource (runResourceT)

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
System
Id Int sqltype=int sql=SystemId
name Text Maybe sqltype=text sql=SystemName
x Double Maybe sqltype=double sql=SystemX
y Double Maybe sqltype=double sql=SystemY
z Double Maybe sqltype=double sql=SystemZ
size Double Maybe sqltype=double sql=SystemSize
deriving Show
|]

connStr = "PATH_TO_DB"

main :: IO ()
main = runStdoutLoggingT $ withSqlitePool connStr 10 $ \pool ->
runResourceT $ flip runSqlPool pool $ do
printMigration migrateAll
res :: [Entity System] <- selectList [] [LimitTo 1]
liftIO $ print res


This is the error:



[Debug#SQL] SELECT "SystemId", "SystemName", "SystemX", "SystemY", "SystemZ", "SystemSize" FROM "System"; [] @(<unknown>
:<unknown> <unknown>:0:0)
edbpc: PersistMarshalError "field x: Expected Double, received: PersistText \"X\""


There is no row in the DB with "X" in the SystemX column.



sqlite> select * from system where systemx like '%X%';
sqlite> select * from system where systemx like '%x%';
sqlite>


What I think is happening is that the field name is being included in the sqlite output rows, and that is being parsed.


I think this because when I add 'OffsetBy 1' to the query, the error goes away and I see the actual first row from the table.


Aucun commentaire:

Enregistrer un commentaire