2

我已经在网上搜索并查看了 postgresql-simple 包的源代码。

查询(或 query_)的结果属于 [QueryResults] 类。获取字段的内容很容易,但是任何人都可以显示一些获取列/字段名称的示例代码吗?PostgreSQL.Simple.FromField 中的 Field 类有一个 name 属性,它返回一个带有列名的 ByteString。但我根本无法从这个列出内容的简单示例中得到:

  conn <- connect con
  xs <- query_ conn "select pk,tfrom from feedback"
  forM_ xs $ \(field1,field2) ->
    putStrLn $ T.unpack field2 ++ " has key " ++ show (field1 :: Int)

到还列出列名称的东西(即pk和tfrom)。

在从(例如,人类可读的诊断、统计)存储过程(或表)中执行 select * 时,获取字段/列名称非常有用,因此我们可以在表或存储过程更改时轻松打印结果而无需更改代码。

提供答案后编辑:这是第一个建议的工作代码(B8 是 ByteString):

  putStrLn $ " is names " ++ (B8.toString (fromJust (name field2))) ++ " " ++ (B8.toString (fromJust (name field1)))

现在,在使用第一个建议时仍然存在获取数据和字段名称的问题,因为代码会将内容修复为 Field 类型 - 它不包含数据本身,仅包含元数据。第二个建议解决了这个问题,现在工作代码如下所示:

  forM_ xs $ \((data1,field1),(data2,field2)) ->
    putStrLn $ " " ++ (B8.toString (fromJust (F.name field1))) ++ " " ++ (B8.toString (fromJust (F.name field2))) ++ " " ++ (T.unpack data2) ++ " " ++ (show (data1 :: Int))

我希望这对其他人也有用。

4

2 回答 2

0

我目前没有 Postgres 实例来检查这一点,但您可以尝试引入instance FromField Field where fromField f = return . const f,然后使用它name来获取字段名称。你可能更普遍地想要

instance FromField a => FromField (a, Field) where
  fromField f bs = (,f) <$> fromField f bs

除非我对这个库的工作方式有很大误解,否则我很惊讶那些实例不在那里。

于 2013-04-17T21:57:30.753 回答
0

恐怕不是一个正确的答案,但评论太长了。

如果您查看库的源代码,您将在 Simple/Internal.hs 中看到以下函数

name Field{..} = unsafePerformIO (PQ.fname result column)

PQ 是对 libpq(标准 PostgreSQL 客户端库)的引用,fname为您提供给定结果集和列索引的字段名。所以,显然它是可用的。

现在,我不认为这个函数是导出的,而且我不知道是否有办法解决这个问题,因为我是 Haskell 新手。显然,您可以轻松地修补源。

但是,我认为即使没有将所有查询列类型转换为文本(或类似内容)的字段名可用,您也无法获得动态结果集。否则 postgresql-simple 会将它们作为 Int 或 Date 或类似的形式返回。

于 2013-04-17T21:46:31.533 回答