为什么 Haskell 不能将 PosgreSQL 字符串分成字段?

发布于 2025-01-13 01:57:00 字数 2324 浏览 4 评论 0原文

我是 PostgreSQL 的新手。简单,所以如果问题很愚蠢,请原谅。

我正在阅读本教程: Postgresql 数据访问使用 Haskell

我得到了第一个可以运行的演示程序。

现在我正在使用这个函数:

retrieveClient :: Connection -> Int -> IO [Only String]
retrieveClient conn cid = query conn "SELECT ticker FROM spot_daily WHERE id = ?" $ (Only cid)

并希望修改它以返回 IO [(String, Integer, Float)] 。

所以我写道:

retrieveClient2 :: Connection -> Float -> IO [(String, Integer, Float)]
retrieveClient2 conn cid =  query conn "SELECT (ticker, timestamp, some_val) FROM spot_daily WHERE p_open > ?" $ (Only cid)

main :: IO ()
main = do
  conn <- connect localPG
  mapM_ print =<< (retrieveClient2 conn 50.0)

我明白了:

MyApp-exe.EXE: Incompatible {errSQLType = "record", errSQLTableOid = Nothing, errSQLField = "row", errHaskellType = "Text", errMessage = "types incompatible"}

在 Haskell 世界里,“在 Hackage 上搜索你想要的类型签名!”是很常见的说法。但从错误消息中我不清楚什么类型的签名会让 GHC 满意。

有没有这样的转换函数?我尝试这样做:

data MyStruct = { field1 :: String, field2 :: Integer, field3 :: Float} deriving (Eq, Show)

retrieveClient3 :: Connection -> Int -> IO [Only MyStruct]
retrieveClient3 conn cid = MyStruct (query conn "SELECT ticker FROM spot_daily WHERE id = ?" $ (Only cid))

但这会导致不同的错误。

作为对评论的回应,以下是 spot_daily 的架构:

                                     Table "public.spot_daily"
  Column   |         Type          | Collation | Nullable |                Default
-----------+-----------------------+-----------+----------+----------------------------------------
 id        | integer               |           | not null | nextval('spot_daily_id_seq'::regclass)
 ticker    | character varying(20) |           | not null |
 epoch     | bigint                |           | not null |
 p_open    | double precision      |           |          |
 p_close   | double precision      |           |          |
 p_high    | double precision      |           |          |
 p_low     | double precision      |           |          |
 synthetic | boolean               |           |          |
Indexes:
    "spot_daily_pkey" PRIMARY KEY, btree (id)

I am new to PostgreSQL.Simple so please forgive if question is dumb.

I am going through this tutorial: Postgresql Data Access with Haskell

I got the first demo program to run.

Now I am taking this function:

retrieveClient :: Connection -> Int -> IO [Only String]
retrieveClient conn cid = query conn "SELECT ticker FROM spot_daily WHERE id = ?" $ (Only cid)

and wish to modify it to return IO [(String, Integer, Float)].

So I wrote:

retrieveClient2 :: Connection -> Float -> IO [(String, Integer, Float)]
retrieveClient2 conn cid =  query conn "SELECT (ticker, timestamp, some_val) FROM spot_daily WHERE p_open > ?" $ (Only cid)

main :: IO ()
main = do
  conn <- connect localPG
  mapM_ print =<< (retrieveClient2 conn 50.0)

and I get this:

MyApp-exe.EXE: Incompatible {errSQLType = "record", errSQLTableOid = Nothing, errSQLField = "row", errHaskellType = "Text", errMessage = "types incompatible"}

It's common in the Haskell world to say, "Search for the type signature you want on Hackage!" but it's not clear to me from the error message what type signature would make GHC happy.

Is there a conversion function for this sort of thing? I tried doing this:

data MyStruct = { field1 :: String, field2 :: Integer, field3 :: Float} deriving (Eq, Show)

retrieveClient3 :: Connection -> Int -> IO [Only MyStruct]
retrieveClient3 conn cid = MyStruct (query conn "SELECT ticker FROM spot_daily WHERE id = ?" $ (Only cid))

but that results in a different error.

In response to a comment, here is schema for spot_daily:

                                     Table "public.spot_daily"
  Column   |         Type          | Collation | Nullable |                Default
-----------+-----------------------+-----------+----------+----------------------------------------
 id        | integer               |           | not null | nextval('spot_daily_id_seq'::regclass)
 ticker    | character varying(20) |           | not null |
 epoch     | bigint                |           | not null |
 p_open    | double precision      |           |          |
 p_close   | double precision      |           |          |
 p_high    | double precision      |           |          |
 p_low     | double precision      |           |          |
 synthetic | boolean               |           |          |
Indexes:
    "spot_daily_pkey" PRIMARY KEY, btree (id)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沉默的熊 2025-01-20 01:57:00

PostgreSQL 类型区分“行”和“记录”。正如所写的(带括号),您的 SQL 查询返回一条记录,该记录不是由元组的 FromRow 实例处理的。

SELECT (ticker, timestamp, some_val) FROM prices_daily WHERE p_open > ?

更改查询(通过删除括号),使其返回一行,postgresql-simple 应该能够处理:

SELECT ticker, timestamp, some_val FROM prices_daily WHERE p_open > ?

PostgreSQL types make a distinction between a "row" and a "record". As written (with parentheses), your SQL query is returning a record, which isn't handled by the FromRow instance for tuples.

SELECT (ticker, timestamp, some_val) FROM prices_daily WHERE p_open > ?

Changing the query (by removing the parentheses), makes it return a row, which postgresql-simple should be able to handle:

SELECT ticker, timestamp, some_val FROM prices_daily WHERE p_open > ?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文