【问题标题】:postgresql select * from users with Haskellpostgresql select * from users with Haskell
【发布时间】:2021-08-24 03:30:06
【问题描述】:

我正在做一个简单的练习,试图从表中选择用户:

main :: IO ()
main = do
    conn <- connect localPG
    mapM_ print =<< (query conn "select * from users where name = ?" (Only ("jane"::String)) :: IO [String])

我得到错误:

Incompatible {errSQLType = "int4", errSQLTableOid = Just (Oid 24592), errSQLField = "id", errHaskellType = "Char", errMessage = ""}

我正在使用https://hackage.haskell.org/package/postgresql-simple-0.6.4/docs/Database-PostgreSQL-Simple.html

PostgreSQL 的返回值似乎无法转换为 https://hackage.haskell.org/package/postgresql-simple-0.4.7.0/docs/Database-PostgreSQL-Simple-FromField.html 中提到的 Haskell 对象

请注意,我通过查询将其转换为 IO [String]。我应该将它投射到什么位置?

【问题讨论】:

  • 您似乎从表中选择了所有内容,而您的类型注释仅指定了一个 String 列。
  • @FyodorSoikin 实际上,比这更糟糕:给定的类型注释指定了多个 Char 列。

标签: postgresql haskell


【解决方案1】:

如果不知道数据库架构,我们无法知道您应该将其转换为什么。但是,对于快速而肮脏的实验,一般的想法是使用与给定表的列具有相同类型且顺序相同的元组。

生产代码通常会使用正确的字段定义一个新的自定义数据类型,并为该类型实现FromRow

【讨论】:

    【解决方案2】:

    请注意,我将查询转换为 IO [String]。我应该将它投射到什么位置?

    不,你没有,这就是问题所在。那不是“强制转换”,而是类型的声明。换句话说,您是在声明“此调用将返回一个行列表,每一行将是一个字符的列”。

    虽然 Haskell 可以在 Haskell 类型系统的范围内使声明为真(通过调用 psql 字符的转换),但这不是 sql 模式的真正类型,也不是您想要的。相反,尽量减少代码的密集度,并提供每列的实际类型。使用 dmwit 建议的快速而简单的方法,您可以执行以下操作:

    main :: IO ()
    main = do
        conn <- connect localPG
        res <- query conn "select * from users where name = ?" (Only ("jane"::String)) :: IO [String]
        mapM_ printRow res
    
    printRow :: -- This is the schema, you tell us
                -- for example only, perhaps something like:
        (String, String, Int, String) -> IO ()
    printRow = print
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      相关资源
      最近更新 更多