Как я могу заставить запрос к базе данных возвращать что-то помимо ввода-вывода с помощью Database.Persistent? - PullRequest
0 голосов
/ 14 июля 2020

Я хотел бы сделать запрос к базе данных, который возвращает результат запроса в виде строки / текста или в виде городов, а не ввода-вывода. Я прочитал большую часть документации по 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}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...