Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从PostgreSQL数据库检索注释_Postgresql_Metadata - Fatal编程技术网

从PostgreSQL数据库检索注释

从PostgreSQL数据库检索注释,postgresql,metadata,Postgresql,Metadata,我正在Postgres数据库上运行一个项目,需要检索数据库中列上的注释,以用作表标题等。我已经看到了一些内置函数(和),但是我还没有找到关于如何使用它们的示例,而对它们的使用已经证明是徒劳的 所以我想知道以前是否有人能做到这一点,如果有,怎么做?好的,所以我在一定程度上解决了这个问题 选择列描述(表id、列编号) ie:选择列描述(36698,2) 这是可行的,但是有没有一种更简单的方法可以做到这一点呢?可能是在所有列上添加所有注释,并使用表名而不是oid???这一切都是通过oid实现的 mat

我正在Postgres数据库上运行一个项目,需要检索数据库中列上的注释,以用作表标题等。我已经看到了一些内置函数(和),但是我还没有找到关于如何使用它们的示例,而对它们的使用已经证明是徒劳的


所以我想知道以前是否有人能做到这一点,如果有,怎么做?

好的,所以我在一定程度上解决了这个问题

选择列描述(表id、列编号)

ie:选择列描述(36698,2)

这是可行的,但是有没有一种更简单的方法可以做到这一点呢?可能是在所有列上添加所有注释,并使用表名而不是oid???

这一切都是通过oid实现的

mat=> SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 'customers';
  oid  
-------
 23208
(1 row)
现在,我有那张桌子的oid,所以我可以问:

mat=> select pg_catalog.obj_description(23208);
  obj_description  
-------------------
 Customers
(1 row)
然后,我可以询问第四列的描述:

mat=> select pg_catalog.col_description(23208,4);
             col_description             
-----------------------------------------
 Customer codes, CHS, FACTPOST, POWER...
(1 row)
如果您想知道当您执行
\dt+
\d+客户
时,
psql
会运行哪些查询,只需使用上个月我问过的
-E
运行即可。如果你仔细阅读,你会在我的博客上看到一些Perl代码,它可以自动提取注释

要提取表的列名,可以使用类似以下内容:

select
     a.attname  as "colname"
    ,a.attrelid as "tableoid"
    ,a.attnum   as "columnoid"
from
    pg_catalog.pg_attribute a
    inner join pg_catalog.pg_class c on a.attrelid = c.oid
where
        c.relname = 'mytable' -- better to use a placeholder
    and a.attnum > 0
    and a.attisdropped is false
    and pg_catalog.pg_table_is_visible(c.oid)
order by a.attnum

然后,您可以使用tableoid、columnoid元组来提取每列的注释(请参见我的问题)。

这对我使用PostBooks 3.2.2 DB是有效的:

select cols.column_name,
(select pg_catalog.obj_description(oid) from pg_catalog.pg_class c where c.relname=cols.table_name) as table_comment
,(select pg_catalog.col_description(oid,cols.ordinal_position::int) from pg_catalog.pg_class c where c.relname=cols.table_name) as column_comment
from information_schema.columns cols
where cols.table_catalog='postbooks' and cols.table_name='apapply'
问候,,
Sylsr

这个答案有点晚了,但它出现在我为研究这个问题而做的谷歌搜索中。我们只需要表描述,但列的方法是相同的。 列说明也在pg_说明表中,由objoid引用

添加此视图:


CREATE OR REPLACE VIEW our_tables AS 
 SELECT c.oid, n.nspname AS schemaname, c.relname AS tablename, d.description,
   pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", 
   c.relhasindex AS hasindexes, c.relhasrules AS hasrules, c.reltriggers > 0 AS hastriggers
   FROM pg_class c
   LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
   LEFT JOIN pg_tablespace t ON t.oid = c.reltablespace
   LEFT JOIN pg_description d ON c.oid = d.objoid
  WHERE c.relkind = 'r'::"char";

ALTER TABLE our_tables OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE, REFERENCES, TRIGGER ON TABLE our_tables TO postgres;
GRANT SELECT ON TABLE our_tables TO public;

然后运行:

SELECT tablename, description FROM our_tables WHERE schemaname = 'public'
该视图是pg_tables视图的修改版本,该视图添加到description列中。
您还可以随意使用视图定义,使其成为单个查询。

增强@Nick和@mat建议:使用
SELECT c.table_schema,c.table_name,c.column_name,pgd.description
FROM pg_catalog.pg_statio_all_tables as st
  inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid)
  inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position
    and  c.table_schema=st.schemaname and c.table_name=st.relname);
选择对象描述('schemaName.tableName'::regclass,'pg_class')
当您有字符串名(不是oid)时

为了避免记住“pg|class”参数,并避免在函数调用时出现难看的连接,如
(tname | |‘.| | schema)::regclass
,这是
obj|u description
的有用重载:

  CREATE FUNCTION obj_description(
      p_rname text, p_schema text DEFAULT NULL, 
      p_catalname text DEFAULT 'pg_class'
  ) RETURNS text AS $f$
     SELECT obj_description((CASE 
        WHEN strpos($1, '.')>0 OR $2 IS NULL OR $2='' THEN $1
        ELSE $2||'.'||$1
     END)::regclass, $3);
  $f$ LANGUAGE SQL IMMUTABLE;
 -- USAGE: obj_description('mytable') 
 --        SELECT obj_description('s.t'); 
 -- PS: obj_description('s.t', 'otherschema') is a syntax error, 
 --     but not generates exception: returns the same as ('s.t') 
现在很容易使用,因为表名(
rname
参数)是一个varchar,可以用一个单独的模式名字段表示,就像在主表和查询中一样


另请参见“”或

小心模式,此代码考虑它们:

SELECT
    cols.column_name, (
        SELECT
            pg_catalog.col_description(c.oid, cols.ordinal_position::int)
        FROM
            pg_catalog.pg_class c
        WHERE
            c.oid = (SELECT ('"' || cols.table_name || '"')::regclass::oid)
            AND c.relname = cols.table_name
    ) AS column_comment
FROM
    information_schema.columns cols
WHERE
    cols.table_catalog    = 'your_database'
    AND cols.table_name   = 'your_table'
    AND cols.table_schema = 'your_schema';
参考资料:


只要有人需要它,就在这里

这里有很多答案,但没有一个像我希望的那样简单。因此,基于之前的答案和当前的postgres 9.4,我创建了以下查询:

SELECT 
    obj_description(format('%s.%s',isc.table_schema,isc.table_name)::regclass::oid, 'pg_class') as table_description,
    pg_catalog.col_description(format('%s.%s',isc.table_schema,isc.table_name)::regclass::oid,isc.ordinal_position) as column_description
FROM
    information_schema.columns isc

它获取表和列描述,没有任何混乱的连接和难看的字符串连接。

我刚刚在这里找到了这个。它将为您提供一个特定表上的所有类型的元数据(类型、默认值、NOTNULL标志、长度、注释、外键名、主键名)。它似乎工作得很好

SELECT pg_tables.tablename, pg_attribute.attname AS field, 
    format_type(pg_attribute.atttypid, NULL) AS "type", 
    pg_attribute.atttypmod AS len,
    (SELECT col_description(pg_attribute.attrelid, 
            pg_attribute.attnum)) AS comment, 
    CASE pg_attribute.attnotnull 
        WHEN false THEN 1  ELSE 0  
    END AS "notnull", 
    pg_constraint.conname AS "key", pc2.conname AS ckey, 
    (SELECT pg_attrdef.adsrc FROM pg_attrdef 
        WHERE pg_attrdef.adrelid = pg_class.oid 
        AND pg_attrdef.adnum = pg_attribute.attnum) AS def 
FROM pg_tables, pg_class 
JOIN pg_attribute ON pg_class.oid = pg_attribute.attrelid 
    AND pg_attribute.attnum > 0 
LEFT JOIN pg_constraint ON pg_constraint.contype = 'p'::"char" 
    AND pg_constraint.conrelid = pg_class.oid AND
    (pg_attribute.attnum = ANY (pg_constraint.conkey)) 
LEFT JOIN pg_constraint AS pc2 ON pc2.contype = 'f'::"char" 
    AND pc2.conrelid = pg_class.oid 
    AND (pg_attribute.attnum = ANY (pc2.conkey)) 
WHERE pg_class.relname = pg_tables.tablename  
--    AND pg_tables.tableowner = "current_user"() 
    AND pg_attribute.atttypid <> 0::oid  
    AND tablename='your_table' 
ORDER BY field ASC
选择pg_tables.tablename、pg_attribute.attname作为字段,
将类型(pg_attribute.atttypid,NULL)格式化为“类型”,
pg_attribute.atttypmod作为len,
(选择列描述(pg_attribute.attrelid,
pg_attribute.attnum)作为注释,
CASE pg_attribute.attnotnull
如果为false,则为1,否则为0
以“notnull”结尾,
pg_constraint.conname为“key”,pc2.conname为ckey,
(从pg_attrdef中选择pg_attrdef.adsrc
其中pg_attrdef.adrelid=pg_class.oid
和pg_attrdef.adnum=pg_attribute.attnum)作为def
从pg_表,pg_类
在pg_class.oid=pg_attribute.attrelid上连接pg_属性
和pg_attribute.attnum>0
pg_constraint上的左连接pg_constraint.contype='p':“char”
和pg_constraint.conrelid=pg_class.oid和
(pg_attribute.attnum=ANY(pg_constraint.conkey))
将pg_约束作为pc2上的pc2左连接。contype='f':“char”
pc2.conrelid=pg_class.oid
和(pg_attribute.attnum=ANY(pc2.conkey))
其中pg_class.relname=pg_tables.tablename
--和pg_tables.tableowner=“当前用户”()
和pg_attribute.atttyped 0::oid
和tablename='your_table'
按字段ASC订购

来源:

我访问了如下表格注释:

select c.relname table_name, pg_catalog.obj_description(c.oid) as comment from pg_catalog.pg_class c where c.relname = 'table_name';
以及专栏评论:

SELECT c.column_name, pgd.description FROM pg_catalog.pg_statio_all_tables as st inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid) inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position and c.table_schema=st.schemaname and c.table_name=st.relname and c.table_name = 'table_name' and c.table_schema = 'public');

对其他答案中的一个稍作修改,只给出对其有注释的列,这将给出所有列,无论它们是否有注释

select c.table_schema, st.relname as TableName, c.column_name, 
pgd.description
from pg_catalog.pg_statio_all_tables as st
inner join information_schema.columns c
on c.table_schema = st.schemaname
and c.table_name = st.relname
left join pg_catalog.pg_description pgd
on pgd.objoid=st.relid
and pgd.objsubid=c.ordinal_position
where st.relname = 'YourTableName';

如果您只需要在其他数据中显示列的
注释
,您还可以使用:

\d+ my_table

要显示所有表的所有列中的注释,请执行以下操作:

SELECT
    cols.table_name,
    cols.column_name, (
    SELECT
        pg_catalog.col_description(c.oid, cols.ordinal_position::int)
    FROM
        pg_catalog.pg_class c
    WHERE
            c.oid = (SELECT ('"' || cols.table_name || '"')::regclass::oid)
      AND c.relname = cols.table_name
) AS column_comment
FROM
    information_schema.columns cols
WHERE
  cols.table_name   IN (SELECT cols.table_name FROM information_schema.columns)
  AND cols.table_catalog = 'your_database_name'
  AND cols.table_schema = 'your_schema_name';
您需要在任何schema/catalog/db之外执行此查询


此查询基于此问题中的另一个答案,该答案仅显示一个表中的注释

我不太了解此代码的工作原理,但它满足我的需要,因此我不必这样做。我遇到了一个案例,其中肯定有表,结果集大小为0。有些东西不是很好,但它是一个多么复杂的查询。PostgreSQL不是很友好,但这是因为每个用户都有自己的(不是标准的)“util库”。下面是我的库的一个函数(
rel_description
),它可以帮助您。它可以工作,但Postgres文档中有一个小提示:obj_description的单参数形式只需要对象OID。它现在被弃用,因为不能保证OID在不同的系统目录中是唯一的;因此,可能会返回错误的注释。下面一行允许在表名上更灵活地使用:
c.oid=(选择(“''''''.| cols.table_name | |')::regclass::oid)和
@jcristovao,您能更好地解释一下吗?我使用这一行是为了指定