postgresqlhaskellpostgresql-simple

postgresql-simple query error


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"}


Solution

  • 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: