如何从字段中获取列名称

时间:2013-04-17 21:19:05

标签: postgresql haskell

我搜索了网页并查看了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)))

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

  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))

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

2 个答案:

答案 0 :(得分:0)

我担心这不是一个正确的答案,但评论的时间太长了。

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

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

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

现在,我不认为这个函数是导出的,我不知道是否有办法绕过,因为我是一个Haskell新手。显然,你可以很容易地修补源。

但是,即使没有将所有查询列类型强制转换为文本(或类似的东西),但我认为您无法拥有动态结果集。否则postgresql-simple会将它们返回为Int或Date或其他类似的东西。

答案 1 :(得分: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

除非我对这个图书馆的运作方式有误,否则我很惊讶那些情况不在那里。