Haskell ScottyM() 函数内的数据库查询
Haskell database query inside ScottyM() function
我正在尝试编写简单的休息 API。我使用 Database.SQLite.Simple、Scotty 和 Aeson。我在 ScottyM() 路由函数中遇到数据库查询问题。当我遇到这样的事情时
routes :: [User] -> ScottyM ()
routes allUsers = do
get "/users/:id" $ do
id <- param "id"
json ([x | x <- allUsers, userId x == id] !! 0)
main = do
conn <- open "data.db"
users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
scotty 3000 (routes users)
一切正常,但在这种情况下,allUsers 只会在服务器启动时更新一次。每次有人问起我都想问问。所以我写了这个:
routes :: Connection -> ScottyM ()
routes conn= do
get "/users/:id" $ do
id <- param "id"
users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
json (users !! id)
main = do
conn <- open "data.db"
scotty 3000 (routes conn)
我收到错误
Couldn't match expected type ‘Web.Scotty.Internal.Types.ActionT
Text IO [a0]’
with actual type ‘IO [User]’
In a stmt of a 'do' block:
users <- (query_
conn "select id, first_name, second_name, team from users" ::
IO [User])
In the second argument of ‘($)’, namely
‘do { id <- param "id";
users <- (query_
conn "select id, first_name, second_name, team from users" ::
IO [User]);
json (users !! id) }’
In a stmt of a 'do' block:
get "/users/:id"
$ do { id <- param "id";
users <- (query_
conn "select id, first_name, second_name, team from users" ::
IO [User]);
json (users !! id) }
如何解决?另外,如果我想要 select * from users where id = id from parameters
?
,如何将参数传递给 sql 查询
get
function's second argument is of type ActionM
. If you investigate further, you'll see this is just shorthand for the more complicated looking ActionT
,e
为Text
,m
为IO
。
因为你的do
块是这种类型的,你不能直接调用IO
函数。您需要使用 liftIO
来获得正确的类型。因此,只需在 query_
调用之前添加一个 liftIO
即可修复它。
项目 wiki 中有一个名为 using scotty with IO 的示例显示了这一点。
我正在尝试编写简单的休息 API。我使用 Database.SQLite.Simple、Scotty 和 Aeson。我在 ScottyM() 路由函数中遇到数据库查询问题。当我遇到这样的事情时
routes :: [User] -> ScottyM ()
routes allUsers = do
get "/users/:id" $ do
id <- param "id"
json ([x | x <- allUsers, userId x == id] !! 0)
main = do
conn <- open "data.db"
users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
scotty 3000 (routes users)
一切正常,但在这种情况下,allUsers 只会在服务器启动时更新一次。每次有人问起我都想问问。所以我写了这个:
routes :: Connection -> ScottyM ()
routes conn= do
get "/users/:id" $ do
id <- param "id"
users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
json (users !! id)
main = do
conn <- open "data.db"
scotty 3000 (routes conn)
我收到错误
Couldn't match expected type ‘Web.Scotty.Internal.Types.ActionT
Text IO [a0]’
with actual type ‘IO [User]’
In a stmt of a 'do' block:
users <- (query_
conn "select id, first_name, second_name, team from users" ::
IO [User])
In the second argument of ‘($)’, namely
‘do { id <- param "id";
users <- (query_
conn "select id, first_name, second_name, team from users" ::
IO [User]);
json (users !! id) }’
In a stmt of a 'do' block:
get "/users/:id"
$ do { id <- param "id";
users <- (query_
conn "select id, first_name, second_name, team from users" ::
IO [User]);
json (users !! id) }
如何解决?另外,如果我想要 select * from users where id = id from parameters
?
get
function's second argument is of type ActionM
. If you investigate further, you'll see this is just shorthand for the more complicated looking ActionT
,e
为Text
,m
为IO
。
因为你的do
块是这种类型的,你不能直接调用IO
函数。您需要使用 liftIO
来获得正确的类型。因此,只需在 query_
调用之前添加一个 liftIO
即可修复它。
项目 wiki 中有一个名为 using scotty with IO 的示例显示了这一点。