Ottenere il tipo di dati di ogni colonna dalla tabella PostGIS?


9

Devo ottenere i tipi di dati di colonna di tutte le colonne in una tabella, inclusi i tipi di geometria. Quello che volevo sapere è se esiste una funzione o SQL che dà qualcosa del genere:

column_name | data_type
------------+--------------
gid         | integer
descr       | character varying(32)
class       | character varying(10)
area        | double precision
geom        | geometry(Polygon,3763)

Da alcune risposte su stackexchange e gis.stackexchange so che posso ottenere alcune delle informazioni con la seguente query:

SELECT 
    g.column_name,
    g.data_type,
    g.character_maximum_length,
    g.udt_name,
    f.type,
    f.srid
FROM 
     information_schema.columns as g JOIN
     geometry_columns AS f 
         ON (g.table_schema = f.f_table_schema and g.table_name = f.f_table_name )
WHERE
    table_schema = 'my_schema_name' and
    table_name = 'my_table_name'

Risultato:

column_name | data_type         | character_maximum_length | udt_name | type    | srid
------------+-------------------+--------------------------+----------+---------+------
gid         | integer           |                          |          |         |
descr       | character varying | 32                       |          |         |
class       | character varying | 10                       |          |         |
area        | double precision  |                          |
geom        | USER-DEFINED      |                          | geometry | Polygon | 3763

Ma esiste un modo più pratico per recuperare le informazioni nel formato di cui ho bisogno? O devo entrare nel "mondo" di CASE WHENstrutture e concatenazione di stringhe per raccogliere tutti gli attributi di colonna in un'unica colonna in quel formato?

La mia paura è che se un tipo di dati non previsto mi sorprende necessitando di altri attributi dalla tabella information_schema.columns. Vale a dire, nella tabella di esempio prima, non ho usato alcun numeric (15,2)tipo di dati, che avrebbe bisogno di usare altri attributi (numeric_precision e numeric_scale) per essere analizzato da CASE WHEN.

Risposte:


14

La teoria sì, anche se potresti trovarla davvero complessa.

  • Ogni tabella (selezionare * da pg_class) ha colonne.
  • Ogni colonna (selezionare * da pg_attribute) ha facoltativamente un numero "typmod".
  • Per i tipi con typmod (selezionare * da pg_type) ci sarà una funzione "typmodout".
  • L'esecuzione della funzione typmod out su un numero typmod restituirà una stringa che può essere concatenata con il nome del tipo per formare il tipo di firma leggibile dall'utente a cui sei abituato (seleziona 'numeric' || numerictypmodout (786441)) (seleziona geography_typmod_out (1107460))

Ma, ehi, psql genera le stringhe che desideri, se guardiamo a ciò che SQL genera, forse la risposta è lì.

Abbastanza sicuro, c'è una funzione magica che accetta un carattere tipografico e un typmod e restituisce la stringa magica.

select a.attname, format_type(a.atttypid, a.atttypmod) from pg_attribute a where attname = 'geog';

Con un join a pg_class dovresti essere in grado di ottenere queste informazioni per tabella.


Non ottengo risultati per, where attname = 'geog'ma = 'geom'funziona. Questo mi dà buoni risultati per i valori MultiPolygon, Point e MultiPoint ma non vedo nulla per i tipi Line o MultiLine. Sono considerati poligoni?
mhkeller,

7

Può essere ottenuto utilizzando una semplice query SQL.

SELECT * from information_schema.columns where table_name='mytablename'


1
Funziona benissimo! Ed ecco un suggerimento: l'output può essere un po 'lungo, quindi potresti voler abilitare il display espanso sulla tua console: \pset pagerdisattivare la pagina, quindi \xabilitare il display espanso.
Modulitos

7

Con l' aiuto di Paul Ramsey l' ho fatto in questo modo:

SELECT a.attname as column_name, format_type(a.atttypid, a.atttypmod) AS data_type
FROM pg_attribute a
JOIN pg_class b ON (a.attrelid = b.relfilenode)
WHERE b.relname = 'my_table_name' and a.attstattarget = -1;

AGGIORNARE

Nel frattempo ho creato una funzione per chiedere un determinato tipo di dati di colonna

CREATE OR REPLACE FUNCTION "vsr_get_data_type"(_t regclass, _c text)
  RETURNS text AS
$body$
DECLARE
    _schema text;
    _table text;
    data_type text;
BEGIN
-- Prepare names to use in index and trigger names
IF _t::text LIKE '%.%' THEN
    _schema := regexp_replace (split_part(_t::text, '.', 1),'"','','g');
    _table := regexp_replace (split_part(_t::text, '.', 2),'"','','g');
    ELSE
        _schema := 'public';
        _table := regexp_replace(_t::text,'"','','g');
    END IF;

    data_type := 
    (
        SELECT format_type(a.atttypid, a.atttypmod)
        FROM pg_attribute a 
        JOIN pg_class b ON (a.attrelid = b.oid)
        JOIN pg_namespace c ON (c.oid = b.relnamespace)
        WHERE
            b.relname = _table AND
            c.nspname = _schema AND
            a.attname = _c
     );

    RETURN data_type;
END
$body$ LANGUAGE plpgsql;

L'utilizzo è:

SELECT vsr_get_data_type('schema_name.table_name','column_name')

-1

se vuoi controllare il tipo di geometria puoi controllare 'udt_name' in 'INFORMATION_SCHEMA.COLUMNS' e usarlo !:

select column_name,udt_name, data_type, character_maximum_length from INFORMATION_SCHEMA.COLUMNS where table_name =g

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.