2008-12-05 6 views
24

Ich führe ein Projekt in einer Postgres-Datenbank aus und muss die Kommentare zu Spalten innerhalb der Datenbank abrufen, die als Tabellenüberschriften und dergleichen verwendet werden sollen. Ich habe gesehen, dass es ein paar eingebaute Funktionen gibt (pg_description und col_description), aber ich war nicht in der Lage, Beispiele zu finden, wie man sie benutzt und herumspielen mit ihnen hat sich als ziemlich sinnlos erwiesen.Abrufen von Kommentaren aus einer PostgreSQL-DB

Also habe ich mich gefragt, ob das schon mal möglich war und wenn ja, wie?

+0

PostgreSQL ist nicht sehr freundlich, aber es ist, weil jeder Benutzer haben Ihre persönliche (nicht standardmäßige) "util-Bibliothek". Unterhalb einer Funktion ('rel_description') meiner Bibliothek kann Ihnen das helfen. –

Antwort

1

Ok, so arbeitete ich es Grad heraus ...

select col_description (Tabelle id, Spaltennummer) ...

dh: select col_description (36698,2);

Das hat funktioniert, aber gibt es einen einfacheren Weg dies zu tun, vielleicht alle Kommentare auf alle Spalten zu bringen und den Tabellennamen anstatt der oid zu benutzen ???

11

Es alle Werke von oid,

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

Jetzt habe ich die oid für die Tabelle, so kann ich fragen:

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

Dann kann ich für die Beschreibung des vierten fragen Säule:

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

Wenn Sie, welche Abfragen tut psql laufen wissen wollen, wenn Sie \dt+ tun oder \d+ customers, führen Sie es einfach mit -E.

+0

"obj_description (object_oid)" ist jetzt veraltet, siehe https://www.postgresql.org/docs/current/static/functions-info.html – alfonx

1

Cool, das funktioniert, um einen einzelnen Kommentar zu bringen, aber gibt es eine Möglichkeit, alle Kommentare aus allen Spalten ohne mehrere Select-Anweisungen oder eine Schleife zu holen?

Und wie Sie dies tun starten mit einer Erklärung:

Wenn Sie wissen möchten, welche fragt tut psql laufen, wenn Sie tun \ dt + oder \ d + Kunden, launche es nur mit -E.

Dank

0

fragte ich a similar question about Postgresql comments im letzten Monat. Wenn Sie das durchforschen, werden Sie in meinem Blog auf einen Perl-Code stoßen, der das Extrahieren eines Kommentars automatisiert.

Um die Spaltennamen einer Tabelle herausziehen, können Sie so etwas wie der folgenden verwenden:

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 

Sie können dann mit dem tableoid, columnoid Tupel zu extrahieren den Kommentar von jeder Spalte (siehe meine Frage) .

4

Dies funktioniert für mich die Postbooks 3.2.2 DB mit:

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' 

Grüße, Sylnsr

+0

Es funktioniert, aber eine kleine Notiz aus der Postgres-Dokumentation: Der Ein-Parameter Die Form von obj_description benötigt nur die Objekt-OID. Es ist jetzt veraltet, da nicht garantiert werden kann, dass OIDs in verschiedenen Systemkatalogen eindeutig sind. Daher könnte der falsche Kommentar zurückgegeben werden. –

0

Diese Antwort ist ein wenig spät, aber es tauchte auf einer Google-Suche bis ich forschte dieses Problem. Wir brauchten nur Tabellenbeschreibungen, aber die Methode wäre für Spalten gleich. Die Spaltenbeschreibungen befinden sich auch in der Tabelle pg_description, auf die von objoid verwiesen wird.

diese Ansicht hinzufügen:


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; 

Dann laufen:

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

Die Ansicht ist eine modifizierte Version der pg_tables anzuzeigen, welche in der Beschreibung Spalte hinzufügt. Sie könnten auch mit der Ansichtsdefinition umgehen, um es zu einer einzigen Abfrage zu machen.

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

ich verstehe nicht ganz, wie dieser Code funktioniert, aber tut, was ich brauche, also muss ich nicht. – ssc

2

Enhance für @ Nick und @mat Vorschläge:
SELECT obj_description('schemaName.tableName'::regclass, 'pg_class'); verwenden, wenn Sie string name (nicht oid).

Um zu vermeiden, ‚pg_class‘ Parameter zu erinnern, und hässlich Verkettungen an den Funktionsaufrufen, wie (tname||'.'||schema)::regclass, eine nützliche Überlastung für obj_description zu vermeiden:

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

Jetzt ist einfach zu bedienen, weil die Tabellennamen (rname Parameter) ist ein varchar und kann mit einem getrennten Feld für Schemaname, wie in den Haupttabellen und Abfragen ausgedrückt werden.

Siehe auch "Getting list of table comments in PostgreSQL" oder das new pg9.3 Guide

8

mit Schemata Achten Sie darauf, diesen Code betrachten sie:

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

Referenzen:

+1

Die folgende Zeile ermöglicht mehr Flexibilität bei Tabellennamen: '' 'c.oid = (SELECT ('"' || cols.tabellenname || '"') :: regclass :: oid) AND''' – jcristovao

+0

@jcristovao Kannst du es bitte besser erklären? –

+0

Ich benutze diese Zeile, so dass ich den Tabellenname nur einmal in der '' 'WHERE''' Klausel angeben kann. Die einfache Lösung von '' 'cols.table_name''' ist jedoch mit Tabellennamen wie' 'WeirdCaps'' fehlgeschlagen – jcristovao

2

Nur hier zu sein, wenn jemand es braucht.

Es gibt viele Antworten hier, aber keine von ihnen war so einfach, wie ich es gerne hätte. So, basierend auf früheren Antworten und aktuelle Postgres 9.4, ich habe diese Abfrage erstellt:

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 

Es holt Tabellen- und Spaltenbeschreibungen, ohne verwirrend verbindet und hässlich Zeichenfolge Verkettungen.

0

Ich habe das gerade hier gefunden. Sie erhalten alle Arten von Metadaten zu einer bestimmten Tabelle (Typ, Standardwert, nicht Null-Flag, Länge, Kommentar, Name des Fremdschlüssels, Name des Primärschlüssels). Es scheint gut zu funktionieren.

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 

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

0

I Tabelle Kommentare wie folgt zugegriffen:

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

und Spalte Kommentare thusly:

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