Как вставить значение байта с помощью postgresql-simple в Haskell - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть таблица, определенная как

CREATE TABLE users (id SERIAL PRIMARY KEY, val BYTEA);

Затем я хочу сериализовать мою структуру данных с помощью binary и сохранить в таблице, а затем извлечь и десериализовать обратно.

{-# LANGUAGE OverloadedStrings, DeriveAnyClass #-}
import Control.Monad (forM_)
import Data.Binary (encode, decode, Binary)
import Database.PostgreSQL.Simple
import GHC.Generics (Generic)

data User = { name :: Text, email :: Text } deriving (Show, Generic, Binary)
main = do
  conn <- connect --...
  let encoded = encode User {name = "me", email = "me@home.net" }
  execute conn "INSERT INTO users(val) values(?)" $ Only encoded
  rs <- query_ conn "SELECT id, val FROM users"
  forM_ rs $ \(id,val) ->
    putStrLn $ (show (id :: Int)) ++ ": " ++ show (decode val :: User)

Но я получаю ошибку Data.Binary.Get.runGet at position 0: not enough bytes.

Запрос

SELECT * FROM users;

дает

 id | val 
----+-----
  1 | \x

Я не могу понять, как сопоставить ByteString с 'BYTEA`s. Согласно документам все должно быть в порядке. Что я делаю не так?

1 Ответ

0 голосов
/ 06 сентября 2018

Исправлено путем замены строки

execute conn "INSERT INTO users(val) values(?)" $ Only encoded

на

execute conn "INSERT INTO users(val) values(?)" $ Only $ Binary encoded

Это потому, что toField(ByteString) дает Escape, тогда как toField(Binary ByteString) дает EscapeByteA

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...