简体   繁体   English

如何从字段获取列名

[英]How to get column names from fields

I have searched the web and looked in the source code of the postgresql-simple package. 我已经在网上搜索并查看了postgresql-simple软件包的源代码。

The results of a query (or query_) are of type class [QueryResults]. 查询(或query_)的结果类型为[QueryResults]类。 It is easy to get the contents of the fields, but can anyone show some example code for getting the column/field names? 获取字段的内容很容易,但是没有人可以显示一些示例代码来获取列/字段名称吗? The Field class from PostgreSQL.Simple.FromField has a name attribute returning a ByteString with the column name. PostgreSQL.Simple.FromField中的Field类具有name属性,该属性返回带有列名的ByteString。 But I am simply unable to get from this simple example listing the contents: 但是我无法从列出内容的这个简单示例中得到:

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

to something that also lists the name of the columns (ie pk and tfrom). 也会列出列名称的内容(即pk和tfrom)。

Getting the field/column names is very useful when doing select * from a (say, human-readable diagnostics, statistics) stored procedure (or table) so we can easily print the results without changing the code when the table or stored procedure changes. 从(例如,人类可读的诊断,统计信息)存储过程(或表)中执行select *时,获取字段/列名称非常有用,因此当表或存储过程发生更改时,我们可以轻松地打印结果而无需更改代码。

Edited after answer was provided: Here is the working code with the first suggestion (B8 is ByteString): 提供答案后进行编辑:这是第一个建议的工作代码(B8是ByteString):

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

Now, there still remains the problem of getting both the data and field names when using the first suggestion as the code will fix the contents to type Field - which does not contain the data itself, just metadata. 现在,仍然存在在使用第一个建议时同时获取数据名称和字段名称的问题,因为代码会将内容固定为类型Field-该类型不包含数据本身,而仅包含元数据。 The second suggestion fixes that, now the working code looks like this: 第二个建议解决了,现在工作代码如下所示:

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

I hope this proves useful for someone else as well. 我希望这对其他人也有用。

Not a proper answer I'm afraid, but too long for a comment. 恐怕这不是一个正确的答案,但是评论太久了。

If you look at the library's source, you'll see the following function in Simple/Internal.hs 如果查看库的源代码,您将在Simple / Internal.hs中看到以下功能

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

The PQ is a reference to libpq (the standard PostgreSQL client library) and fname gets you a fieldname given a resultset and column index. PQ是对libpq(标准PostgreSQL客户端库)的引用,而fname为您提供给定结果集和列索引的字段名。 So, clearly it's available. 因此,显然可以使用。

Now, I don't think this function is exported, and I don't know if there's a way around that since I'm a Haskell newbie. 现在,我不认为该函数会导出,而且我是Haskell新手,所以我不知道是否有解决方法。 Clearly you could patch the source easily enough. 显然,您可以轻松地修补源。

However, I don't think you'll be able to have a dynamic resultset even with the fieldname available without casting all the query column-types to text (or something similar). 但是,我认为即使具有可用的字段名,您也无法拥有动态结果集,而无需将所有查询列类型都转换为文本(或类似内容)。 Otherwise postgresql-simple will return them as Int or Date or some such. 否则,postgresql-simple将以Int或Date或类似形式返回它们。

I don't have a Postgres instance around to check this at the moment, but you could try introducing instance FromField Field where fromField f = return . const f 我目前没有Postgres实例可以检查此情况,但是您可以尝试引入instance FromField Field where fromField f = return . const f instance FromField Field where fromField f = return . const f and then use name to get the name of your fields out. instance FromField Field where fromField f = return . const f ,然后使用name来获取字段的名称。 You might even more generally want 您可能甚至更想要

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

Unless I'm pretty mistaken on how this library works, I'm pretty surprised those instances aren't in there. 除非我对这个库的工作方式很误解,否则我很惊讶那些实例不在其中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM