私はhaskellを初めて使っていて正直に苦労しています。しかし、それは私の考えを広げるので、ここで私たちは行く。 私は、Postgres DBを照会し、結果をJSONとして返す本当にシンプルなWebサーバーを実行しようとしています。Haskell SpockとPostgres-Simple - クエリテーブルとjsonとしての返信
クエリは絶対に簡単です:「IDを選択し、ID = 1 MYTABLEからデータ」
しかし、Haskellの型システムは、今の私を殺して、自分の行動の最終型が一致しません。 。 私はSpockとPostgreSQL-Simpleをコンボとして使用しています。
ほとんどのチュートリアルは、私がやりたいことや難しいことのために簡単なものです。私はどこかにいて、ハスケルの理解が不足しています。以前の多くの問題を単純なコピーと貼り付けで解決し、単純なバージョンの作業を得ました。
しかし、私がルート変数を渡そうとすると、私は失敗しています。 私の働くバージョンです。
{-# 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])
それから私はそのために、私はまた、PostgreSQLの-シンプルを変更する必要があり、ラムダ関数と封筒IDを渡すために試してみてください。それはget "json"
が言うところ私のデータベースの表は、ここでは、「エンベロープ」と呼ばれ、重要な呼び出しがあります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を照会から削除することができます。
完全なソースは、私は誰かがここで私を助けるために時間を持っている願っていますbitbucket
で見つけることができます。 既にお読みいただきありがとうございます。
何ですか?結局のところ、思考の頭痛? ありがとうございます、それは動作します。私は非常に混乱しています。なぜなら2つのパラメータを単純に(parA:Int、parB:Int)することができますが、oneparamでは 'Only'表記をする必要があります。しかし、あなたが私にそれを指摘した後、私はPostgres-Simple Docsのそれについていくつかのコメントを見つけたので、後でそれを理解すると思います。 –
この文脈では、 'Int'を列として、タプルを2つの列と' Only'を1つの列として持つ行と考えることができます。 'query'は行を扱うだけなので、列の中に列を置く必要があります。これは、sqlのinsert文で 'values'を使用するのと少し似ています。あなたは1を渡すことはできません。あなたは 'values(1)'または 'select 1'を必要とします。 – soupi
今より意味があります。ありがとう。 –