Postgres -simple-没有使用“查询”而引起的(torow int)的实例



我是Haskell的新手,并且对此诚实。但这扩大了我的想法,所以我们去了。我正在尝试运行一个非常简单的Web服务器,该网络服务器询问Postgres DB,并应将结果返回为JSON。

查询绝对简单:"从Mytable中选择ID,其中ID = 1"

但是,Haskell的类型系统正在杀死我,而我的动作的最终类型不匹配。我正在使用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])

然后,我尝试通过lambda函数传递信封ID,因为我还需要将PostgreSQL-SIMPLE 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)

我也有问题,即使没有lambda功能,也只能从查询中返回第一项。

可以在bitbucket上找到完整的源

我希望有人有时间在这里帮助我。感谢您的阅读。

错误基本上说的是您不能将Int传递给query作为第三个参数。query期望具有类型ToRow的实例,而Int不是一个。考虑到您只想将一个值传递给query,您可能想做的就是使用Only。因此,该线变为:

query conn  "select id,data from envelope where id = ?" (Only (eid :: Int))

基于汤的帮助,我还找到了Postgres-simple文档中的相应部分。只是为了完成,文档使用单例列表提到了替代语法。因此,您可以简单地使用正方形括号,而不是使用普通括号,并且也可以使用:

query conn "select id,data from envelope where id = ?" [eid :: Int]

此外,特别是在我的示例中,仅从结果中返回第一行更有意义,然后将其简单地直接使用head函数。对于其他需要它的人,这就是您的工作方式:

spock和prelude都包含head功能。为了避免冲突,我决定隐藏Spocks功能,因为我无论如何都没有使用。

在顶部添加到您的脚本:

import Web.Spock hiding(head)

然后将get零件更改为:

get ( "json" <//> var  ) $ eid -> do
      xs<-runQuery $ conn -> 
        query conn  "select id,data from envelope where id = ?" [eid :: Int]
      json $ head (xs::[Envelope])

完成。

相关内容

  • 没有找到相关文章

最新更新