2008-12-05 17 views
24

Estoy ejecutando un proyecto en una base de datos de Postgres y necesito recuperar los comentarios en columnas dentro del DB para usarlos como encabezados de tabla y cosas por el estilo. He visto que hay un par de funciones integradas (pg_description y col_description) pero no he podido encontrar ejemplos sobre cómo usarlas y jugar con ellas ha resultado bastante inútil.Recuperación de comentarios de un DB PostgreSQL

Así que me preguntaba si alguno ha podido hacer esto antes y, de ser así, ¿cómo?

+0

PostgreSQL no es muy amigable, pero es debido a que cada el usuario tiene su "biblioteca de utilidades" personal (no estándar). Debajo de una función ('rel_description') de mi biblioteca, eso puede ayudarte. –

Respuesta

1

Ok, así que trabajé a cabo a nivel ...

seleccione col_description (mesa de identificación, número de columna) ...

es decir: seleccione col_description (36698,2);

Eso funcionó, pero ¿hay una manera más fácil de hacer esto tal vez trayendo todos los comentarios en todas las columnas y usando el nombre de la tabla en lugar del oid?

11

Todo funciona por OID,

mat=> SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 'customers'; 
    oid 
------- 
23208 
(1 row) 

Ahora, tengo el OID para esa tabla, por lo que puede preguntar:

mat=> select pg_catalog.obj_description(23208); 
    obj_description 
------------------- 
Customers 
(1 row) 

Entonces, puedo pedir la descripción de la cuarta columna:

mat=> select pg_catalog.col_description(23208,4); 
      col_description    
----------------------------------------- 
Customer codes, CHS, FACTPOST, POWER... 
(1 row) 

Si usted quiere saber lo que hace consultas psql de ejecución cuando haces \dt+ o \d+ customers, simplemente ejecútelo con -E.

+0

"Obj_description (object_oid)" ahora está en desuso, consulte https://www.postgresql.org/docs/current/static/functions-info.html – alfonx

1

Genial, eso funciona para hacer aparecer un solo comentario, pero ¿hay alguna manera de mostrar todos los comentarios de todas las columnas sin múltiples instrucciones de selección o un ciclo?

Y cómo iniciar esto con una declaración:

Si quieres saber qué consultas se ejecuta psql cuando haces \ dt + o \ d + clientes, simplemente launche con -E.

Gracias

0

me preguntaron a similar question about Postgresql comments mes pasado. Si profundizas en eso, encontrarás algún código de Perl en mi blog que automatiza el proceso de extracción de un comentario.

para sacar los nombres de columna de una tabla, puede usar algo como lo siguiente:

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 

A continuación, puede utilizar el tableoid, tupla columnoid para extraer el comentario de cada columna (véase mi pregunta) .

4

Esto funciona para mí usando los 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' 

Regards, Sylnsr

+0

Funciona, pero una pequeña nota de los documentos de Postgres: El parámetro de un solo La forma de obj_description requiere solo el OID del objeto. Ahora está en desuso, ya que no hay garantía de que los OID sean únicos en diferentes catálogos de sistemas; por lo tanto, se podría devolver el comentario incorrecto. –

0

Esta respuesta es un poco tarde, pero apareció en una búsqueda en Google que hice para la investigación este problema. Solo necesitábamos descripciones de tabla, pero el método sería el mismo para las columnas. Las descripciones de las columnas están en la tabla pg_description también, referenciadas por objoid.

Añadir este punto de vista:


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; 

A continuación, ejecute:

SELECT tablename, description FROM our_tables WHERE schemaname = 'public'

La vista es una versión modificada de los pg_tables ver que se suma en la columna de la descripción. También podría consultar la definición de la vista para convertirla en una sola consulta.

25
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); 
+1

No entiendo muy bien cómo funciona este código, pero hace lo que necesito, así que no es necesario. – ssc

2

se destaca por sugerencias @ Nick y @mat: El uso
SELECT obj_description('schemaName.tableName'::regclass, 'pg_class'); cuando se tiene el nombre de cadena (no OID).

Para evitar recordar parámetro 'pg_class', y para evitar concatenaciones feas en las llamadas a funciones, como (tname||'.'||schema)::regclass, una sobrecarga útil para obj_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') 

Ahora es fácil de usar, ya que el nombre mesa (parámetro rname) es un varchar y se puede expresar con un campo separado para nombre de esquema, como en las tablas principales y las consultas.

Véase también "Getting list of table comments in PostgreSQL" o la new pg9.3 Guide

8

Tenga cuidado con los esquemas, este código los consideran:

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'; 

Referencias:

+1

La siguiente línea permite una mayor flexibilidad en los nombres de tablas: '' 'c.oid = (SELECT ('"' || cols.table_name || '"') :: regclass :: oid) AND''' – jcristovao

+0

@jcristovao , ¿Puedes explicarlo mejor, por favor? –

+0

Utilizo esa línea para poder especificar el nombre de tabla solo una vez en la cláusula '' 'WHERE'''. Sin embargo, la solución simple de '' 'cols.table_name''' falló con nombres de tablas como' '' WeirdCaps''' – jcristovao

2

Sólo para estar aquí si alguien lo necesitara.

Aquí hay muchas respuestas, pero ninguna de ellas fue tan simple como me gustaría que fuera. Por lo tanto, en base a las respuestas anteriores y actuales Postgres 9.4, he creado esta consulta:

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 

Se obtiene descripciones de tablas y columnas, sin ningún tipo de uniones y confuso concatenaciones de cadenas feas.

0

Acabo de encontrar esto aquí. Le proporcionará todo tipo de metadatos en una tabla específica (tipo, valor predeterminado, indicador no nulo, longitud, comentario, nombre de clave externa, nombre de clave principal). Parece que funciona bien.

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 

Fuente: http://golden13.blogspot.de/2012/08/how-to-get-some-information-about_7.html

0

Accedí comentarios de mesa como esta:

select c.relname table_name, pg_catalog.obj_description(c.oid) as comment from pg_catalog.pg_class c where c.relname = 'table_name'; 

y comentarios de la columna así:

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'); 
Cuestiones relacionadas