Come ottenere un elenco di nomi di colonne e tipo di dati di una tabella in PostgreSQL?


95

Con la seguente query, possiamo ottenere un elenco di nomi di colonne e tipi di dati di una tabella in PostgreSQL.


plsql \ gdesc è anche un'opzione. La caratteristica interessante è che potrebbe descrivere intere query (utile per quelle complesse ad hoc) ma funziona anche per scenari semplificati SELECT * FROM tab_name \gdesc.
Lukasz Szozda

Risposte:


136

Apri la psqlriga di comando e digita:

\d+ table_name

2
Non capisco perché questa non sia la risposta più votata.
mjezzi

20
Questo è incompleto in quanto OP potrebbe volerlo fare a livello di codice in codice SQL, non solo tramite psql.
Luca

Postgres lo fa in modo programmatico, quindi avvia postgres con il flag '-E': psql -Ee per ogni comando backslash il rispettivo SQL verrà visualizzato prima del risultato del comando.
karatedog

122
select column_name,data_type 
from information_schema.columns 
where table_name = 'table_name';

con la query precedente puoi colonne e il suo tipo di dati


5
Ciò non darà la risposta giusta per i tipi definiti dall'utente (ad esempio, le colonne Geometria e Geografia create da ogr2ogr , che sono della forma geometry(Geometry,[SRID])).
GT.

1
Si potrebbe anche usare table_catalog = 'my_database'e table_schema = 'my_schema'per ottenere solo colonne da una tabella specifica di uno schema specifico di un database specifico.
Marco Mannes

Posso suggerire a tutti, se stai cercando di costruire su questo codice. Usa il pg_cataloge non il information_schema. L' information_schemaha qualche SQL piuttosto semplice e universale, ma è più lento, perché è di più alto livello.
Daniel L. VanDenBosch

24
SELECT
        a.attname as "Column",
        pg_catalog.format_type(a.atttypid, a.atttypmod) as "Datatype"
    FROM
        pg_catalog.pg_attribute a
    WHERE
        a.attnum > 0
        AND NOT a.attisdropped
        AND a.attrelid = (
            SELECT c.oid
            FROM pg_catalog.pg_class c
                LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relname ~ '^(hello world)$'
                AND pg_catalog.pg_table_is_visible(c.oid)
        );

Cambia il mondo di Hello con il nome del tuo tavolo

Maggiori informazioni su di esso: http://www.postgresql.org/docs/9.3/static/catalog-pg-attribute.html


2
Funziona, ma perché stai usando c.relname ~ '^(hello world)$invece di semplicemente c.relname = 'hello world'?
Thomas

18

Non dimenticare di aggiungere il nome dello schema nel caso tu abbia più schemi con gli stessi nomi di tabella.

SELECT column_name, data_type 
FROM information_schema.columns
WHERE table_name = 'your_table_name' AND table_schema = 'your_schema_name';

o usando psql:

\d+ your_schema_name.your_table_name

8

Una versione che supporta la ricerca dei nomi di colonna e dei tipi di una tabella in uno schema specifico e utilizza JOIN senza subquery

SELECT
    pg_attribute.attname AS column_name,
    pg_catalog.format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS data_type
FROM
    pg_catalog.pg_attribute
INNER JOIN
    pg_catalog.pg_class ON pg_class.oid = pg_attribute.attrelid
INNER JOIN
    pg_catalog.pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE
    pg_attribute.attnum > 0
    AND NOT pg_attribute.attisdropped
    AND pg_namespace.nspname = 'my_schema'
    AND pg_class.relname = 'my_table'
ORDER BY
    attnum ASC;

Questa è la mia risposta preferita perché realizza 2 cose. Usa il pg_cataloge ti obbliga a specificare lo schema. Se stai stipando ogni cosa nello schema pubblico, personalmente credo che sia una cattiva strategia. Man mano che il tuo progetto cresce, sarà difficile mantenere le cose organizzate. IMHO
Daniel L. VanDenBosch

7

Risposta Pratik aggiornata per supportare più schemi e nullable:

SELECT
    "pg_attribute".attname                                                    as "Column",
    pg_catalog.format_type("pg_attribute".atttypid, "pg_attribute".atttypmod) as "Datatype",

    not("pg_attribute".attnotnull) AS "Nullable"
FROM
    pg_catalog.pg_attribute "pg_attribute"
WHERE
    "pg_attribute".attnum > 0
    AND NOT "pg_attribute".attisdropped
    AND "pg_attribute".attrelid = (
        SELECT "pg_class".oid
        FROM pg_catalog.pg_class "pg_class"
            LEFT JOIN pg_catalog.pg_namespace "pg_namespace" ON "pg_namespace".oid = "pg_class".relnamespace
        WHERE
            "pg_namespace".nspname = 'schema'
            AND "pg_class".relname = 'table'
    );

2
    SELECT DISTINCT
        ROW_NUMBER () OVER (ORDER BY pgc.relname , a.attnum) as rowid , 
        pgc.relname as table_name ,
        a.attnum as attr,
        a.attname as name,
        format_type(a.atttypid, a.atttypmod) as typ,
        a.attnotnull as notnull, 
        com.description as comment,
        coalesce(i.indisprimary,false) as primary_key,
        def.adsrc as default
    FROM pg_attribute a 
    JOIN pg_class pgc ON pgc.oid = a.attrelid
    LEFT JOIN pg_index i ON 
        (pgc.oid = i.indrelid AND i.indkey[0] = a.attnum)
    LEFT JOIN pg_description com on 
        (pgc.oid = com.objoid AND a.attnum = com.objsubid)
    LEFT JOIN pg_attrdef def ON 
        (a.attrelid = def.adrelid AND a.attnum = def.adnum)
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = pgc.relnamespace

    WHERE 1=1 
        AND pgc.relkind IN ('r','')
        AND n.nspname <> 'pg_catalog'
        AND n.nspname <> 'information_schema'
        AND n.nspname !~ '^pg_toast'

    AND a.attnum > 0 AND pgc.oid = a.attrelid
    AND pg_table_is_visible(pgc.oid)
    AND NOT a.attisdropped
    ORDER BY rowid
    ;

Si prega di includere il contesto nel codice. Inoltre, come lo espandi ad altri schemi?
Daniel L. VanDenBosch

2

Per rendere questo argomento "più completo".

Ho richiesto i nomi delle colonne e i tipi di dati su un'istruzione SELECT (non una tabella).

Se si desidera eseguire questa operazione su un'istruzione SELECT anziché su una tabella esistente effettiva, è possibile eseguire le seguenti operazioni:

DROP TABLE IF EXISTS abc;
CREATE TEMPORARY TABLE abc AS
-- your select statement here!
SELECT 
    *
FROM foo
-- end your select statement
;

select column_name, data_type 
from information_schema.columns 
where table_name = 'abc';
DROP IF EXISTS abc;

Breve spiegazione, crea una tabella (temporanea) dell'istruzione select, che puoi "richiamare" tramite la query fornita da (tra gli altri) @a_horse_with_no_name e @selva.

Spero che sia di aiuto.


2

senza menzionare lo schema puoi anche ottenere i dettagli richiesti Prova questa query->

selezionare column_name, data_type da information_schema.columns dove table_name = 'table_name';


0

Per ottenere informazioni sulla colonna della tabella, puoi utilizzare:

\dt+ [tablename]

Per ottenere informazioni sul tipo di dati nella tabella, puoi utilizzare:

\dT+ [datatype]

1
\ dt + tablename ottiene le informazioni sulla tabella, ma non sulla colonna
zhihong

0
SELECT column_name,data_type 
FROM information_schema.columns 
WHERE
table_name = 'your_table_name' 
AND table_catalog = 'your_database_name' 
AND table_schema = 'your_schema_name';

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo su come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
Paperino
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.