问题
EDIT: I now have a better idea of what is going wrong. When I perform that query in plain old psql
, I get the following result:
lwm@verbos
=# SELECT * FROM gerund LIMIT1;
infinitive │ gerund │ gerund_english
────────────┼─────────────┼────────────────
abandonar │ abandonando │ abandoning
So, I am getting back 3 strings? However, I say that I am getting back IO [Only String]
. I am sure it is my type signature here that is messing things up ...
I am trying to make a simple query using the postgresql-simple
library with Haskell
. My code is pasted below along with the error I am seeing. Anyone got any ideas?
My database is called verbos
and within it, I have a table called gerund
. I am able to run a query_
that contains: conn "SELECT 2 + 2"
and that works fine. I can also connect to my database with the default data as specified with the default information (password = 'postgres' : psql -h localhost -p 5432 -U postgres
(from the docs[1])
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad
import Control.Applicative
import Database.PostgreSQL.Simple
main = do
conn <- connect defaultConnectInfo {
connectPassword = "postgres",
connectDatabase = "verbos"
}
mapM_ print =<< (query_ conn "SELECT * FROM gerund LIMIT 1" :: IO [Only String])
Gives me the following error:
ConversionFailed {errSQLType = "3 values: [(Basic {typoid = Oid 1043, typcategory = 'S', typdelim = ',', typname = \"varchar\"},Just \"abandonar\"),(Basic {typoid = Oid 1043, typcategory = 'S', typdelim = ',', typname = \"varchar\"},Just \"abandonando\"),(Basic {typoid = Oid 1043, typcategory = 'S', typdelim = ',', typname = \"varchar\"},Just \"abandoning\")]", errSQLTableOid = Nothing, errSQLField = "", errHaskellType = "1 slots in target type", errMessage = "mismatch between number of columns to convert and number in target type"}
回答1:
OK, Thanks to @AlpMestanogullari, @muistooshort, I got an answer here. My final code is:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Applicative
import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.FromRow
data Gerund = Gerund {
f :: String,
s :: String,
t :: String
} deriving (Show)
instance FromRow Gerund where
fromRow = Gerund <$> field <*> field <*> field
main = do
conn <- connect defaultConnectInfo {
connectPassword = "postgres",
connectDatabase = "verbos"
}
mapM_ print =<< (query_ conn q :: IO [Gerund])
where q = "SELECT * FROM gerund LIMIT 1"
Notes:
- Knowing that my result contained 3 result columns, I needed to define a
type
that had 'space' for the results (f
,s
andt
in theGerund
type) - I followed the docs[1] for FromRow closely to get my
type
andinstance
defined. - You need to import
import Database.PostgreSQL.Simple.FromRow
to access things likefield
.
来源:https://stackoverflow.com/questions/26952685/postgresql-simple-query-error