Я хотел бы сделать запрос к базе данных, который возвращает результат запроса в виде строки / текста или в виде городов, а не ввода-вывода. Я прочитал большую часть документации по Persistent, но у меня проблемы с пониманием типов. Что наиболее примечательно для меня, так это то, что у меня есть именно то, что я должен sh вернуть, хранится в переменной dbCity :: Cities
в последней строке фрагмента кода. Я пробовал поиграть с типами, включая попытку возврата и Either (IO ()) Cities
, но мне не удалось выровнять типы.
Я начинаю задаваться вопросом, нужно ли мне использовать трансформатор, который может запускать ввод-вывод, но возвращать другой тип. Обратите внимание, что я импортировал unliftIO, так как эта функция кажется приблизительной к тому, что я хотел бы сделать.
С другой стороны, я уверен, что есть более простой способ сделать это, используя существующие функции в Persistent библиотека.
{-# MANYPRAGMAS #-}
module PostgresSupport where
import Database.Persist
import Database.Persist.TH
import Database.Persist.Postgresql
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger (runStderrLoggingT)
import Data.Text (Text, pack)
import UnliftIO (unliftIO)
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Cities
name Text
state_id Int
state_code Text
country_id Int
country_code Text
latitude Double
longitude Double
CityName name
deriving Show Read
|]
connStr :: ConnectionString
connStr = "not important for this demonstration"
queryCity :: String -> IO ()
queryCity city = runStderrLoggingT $ withPostgresqlPool connStr 10 $ \pool -> liftIO $ do
flip runSqlPersistMPool pool $ do
maybeCity <- getBy $ CityName (pack city)
case maybeCity of
Nothing -> liftIO $ putStrLn ("Cannot find city " ++ show city)
Just (Entity key dbCity) -> liftIO $ print dbCity
В реплике:
> queryCity "New Bedford"
[Debug#SQL] SELECT "id","name","state_id","state_code","country_id","country_code","latitude","longitude" FROM "cities" WHERE "name"=?; [PersistText "New Bedford"]
Cities {citiesName = "New Bedford", citiesState_id = 1433, citiesState_code = "MA", citiesCountry_id = 233, citiesCountry_code = "US", citiesLatitude = 41.63526, citiesLongitude = -70.92701}