I have defined a PostgreSQL table as follows:
> \d+ public."Users"
Table "public.Users"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
-------------+--------------------------+-----------+----------+-------------------------------------+----------+-------------+--------------+-------------
id | integer | | not null | nextval('"Users_id_seq"'::regclass) | plain | | |
username | character varying(255) | | not null | | extended | | |
userId | character varying(255) | | | | extended | | |
I am trying to query that table using postgresql-simple
:
maybeUsername <- liftIO (listToMaybe <$> query conn "SELECT username FROM public.\"Users\" WHERE \"userId\" = ?" (Only userId) :: IO (Maybe String))
case maybeUsername of
Just username -> liftIO $ putStrLn $ "Username is " ++ username
Nothing -> liftIO $ putStrLn $ "Could not find a record for userId " ++ userId
For some reason I am getting a following error:
Incompatible {errSQLType = "varchar", errSQLTableOid = Just (Oid 24782), errSQLField = "username", errHaskellType = "Char", errMessage = ""}
Any ideas how to fix it?
The library struggles to infer the type when a single column is returned (documented here: https://hackage.haskell.org/package/postgresql-simple-0.6.5/docs/Database-PostgreSQL-Simple.html#g:4). Hence we need to fix that by doing Only String
instead of String
.
This way it works as expected:
usernames <- liftIO (query conn "SELECT username FROM public.\"Users\" WHERE \"userId\" = ?" (Only userId) :: IO [Only String])
liftIO $ putStrLn $ "Usernames are " ++ intercalate ", " (map fromOnly usernames)