我是haskell的新手,並且對它有誠實的困難時期。但它擴展了我的思想,所以我們走了。 我想運行一個非常簡單的Web服務器,查詢Postgres數據庫,並應該返回結果爲JSON。Haskell Spock和Postgres-Simple - 查詢表並返回爲json
查詢是絕對簡單: 「選擇ID,從MYTABLE數據其中id = 1」
但是哈斯克爾的類型系統是殺害我現在和我的行動的最終類型不匹配。 我使用Spock和PostgreSQL-Simple作爲組合。
大多數教程要麼簡單的爲我想要做什麼或困難。我處於中間地帶,錯過了許多Haskell的理解,很多我以前通過簡單的複製和粘貼已經解決了的問題,並且得到了一個簡單的版本。
但是,只要我嘗試傳遞一個路由變量,我就失敗了。 這是我的工作版本。我的數據庫表是這裏所說的「信封」中,重要的電話是在那裏說:get "json"
:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
module Main where
import Web.Spock
import Web.Spock.Config
import Database.PostgreSQL.Simple
import Data.Pool
import Data.Aeson (ToJSON(toJSON), object, (.=),Value)
import Database.PostgreSQL.Simple.FromRow
type AppAction a = SpockActionCtx() Connection AppSession AppState a
data AppState = EmptyState
data AppSession = EmptySession
data Envelope = Envelope { envId :: Int, envData :: Value } deriving Show
instance FromRow Envelope where
fromRow = Envelope <$> field <*> field
instance ToJSON Envelope where
toJSON (Envelope envA envB) = object [ "id" .= envA, "data" .= envB ]
main :: IO()
main =
do pool<-createPool (connect (ConnectInfo "localhost" 5432 "" "" "envelopes")) close 1 10 10
spockCfg <- defaultSpockCfg EmptySession (PCPool pool) EmptyState
runSpock 8080 (spock spockCfg app)
app :: SpockM Connection AppSession AppState()
app = do
get root $
text "Hello World!"
get "json" $ do
xs<-runQuery $ \conn ->
query_ conn "select id,data from envelope where id = 1"
json (xs::[Envelope])
然後我嘗試在信封ID通過具有拉姆達功能,我還需要修改PostgreSQL,簡單query_
到query
:
get ("json" <//> var ) $ \eid -> do
xs<-runQuery $ \conn ->
query conn "select id,data from envelope where id = ?" (eid :: Int)
json (xs::[Envelope])
我得到的錯誤說:
No instance for (ToRow Int) arising from a use of ‘query’
In the expression:
query conn "select id,data from envelope where id = ?" (eid :: Int)
In the second argument of ‘($)’, namely
‘\ conn
-> query
conn "select id,data from envelope where id = ?" (eid :: Int)’
In a stmt of a 'do' block:
xs <- runQuery
$ \ conn
-> query
conn "select id,data from envelope where id = ?" (eid :: Int)
我也有問題,只返回第一伊特m,即使沒有lambda函數。
全部源代碼可以在bitbucket
找到我希望有人有時間幫我在這裏。 感謝您的閱讀。
什麼,那是什麼?畢竟這種想法令人頭疼? 非常感謝,這是有效的。對於我來說,爲什麼使用兩個參數你可以簡單地做(parA:Int,parB:Int),但使用一個參數你必須使用'Only'符號。但是當你指向我時,我在Postgres-Simple Docs中發現了一些評論,所以我想我以後會理解它。 –
在這種情況下,您可以將「Int」這樣的類型看作一列,把元組看作一行有兩列,將「Only」看作一列一行。 'query'只處理行,所以你需要把你的列放在一行中。這與在sql中的insert語句中使用'values'有點相似。你不能只傳遞1,你需要'values(1)'或'select 1'。 – soupi
現在更有意義。謝謝。 –