Abrufen des Datentyps jeder Spalte aus der PostGIS-Tabelle?

9

Ich muss die Spaltendatentypen aller Spalten in einer Tabelle abrufen, einschließlich der Geometrietypen. Was ich wissen wollte ist, ob es eine Funktion oder SQL gibt, die so etwas gibt:

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

Aus einigen Antworten zu stackexchange und gis.stackexchange weiß ich, dass ich einige der Informationen mit der folgenden Abfrage erhalten kann:

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'

Ergebnis:

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

Aber gibt es eine praktischere Möglichkeit, die Informationen in dem von mir benötigten Format abzurufen? Oder muss ich in die "Welt" der CASE WHENStrukturen und der Verkettung von Zeichenfolgen eintreten , um alle Spaltenattribute in einer einzigen Spalte in diesem Format zu erfassen?

Ich befürchte, wenn mich ein nicht erwarteter Datentyp überrascht, indem er ein anderes Attribut aus der Tabelle information_schema.columns benötigt. Das heißt, in der numeric (15,2)vorherigen Beispieltabelle habe ich keinen Datentyp verwendet, der andere Attribute (numeric_precision und numeric_scale) verwenden müsste, um von einem CASE WHEN analysiert zu werden.

Alexandre Neto
quelle

Antworten:

14

Die Theorie ja, obwohl man sie in der Tat sehr komplex finden könnte.

  • Jede Tabelle (wählen Sie * aus pg_class) hat Spalten.
  • Jede Spalte (wählen Sie * aus pg_attribute) hat optional eine "typmod" -Nummer.
  • Für Typen mit typmod (wählen Sie * aus pg_type) gibt es eine "typmodout" -Funktion.
  • Wenn Sie die typmod out-Funktion für eine typmod-Nummer ausführen, wird eine Zeichenfolge zurückgegeben, die mit dem Typnamen verknüpft werden kann, um die Art der vom Benutzer lesbaren Signatur zu bilden, die Sie gewohnt sind (wählen Sie 'numeric' || numerictypmodout (786441)) (wählen Sie geography_typmod_out aus) (1107460))

Aber, hey, psql generiert die gewünschten Zeichenfolgen. Wenn wir uns ansehen, welches SQL generiert wird, ist die Antwort vielleicht drin.

Sicher genug, es gibt eine magische Funktion, die eine Typ-ID und einen Typ-Mod verwendet und die magische Zeichenfolge zurückgibt.

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

Mit einem Join zu pg_class sollten Sie in der Lage sein, diese Informationen pro Tabelle abzurufen.

Paul Ramsey
quelle
Ich bekomme keine Ergebnisse für, where attname = 'geog'aber = 'geom'es funktioniert. Dies gibt mir gute Ergebnisse für MultiPolygon-, Punkt- und MultiPoint-Werte, aber ich sehe nichts für Linien- oder MultiLine-Typen. Werden diese als Polygone betrachtet?
Mhkeller
7

Es kann mit einer einfachen SQL-Abfrage abgerufen werden.

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

Nilesh Khode
quelle
1
Das funktioniert super! Und hier ein Tipp: Die Ausgabe kann sehr lang sein. Daher möchten Sie möglicherweise die erweiterte Anzeige auf Ihrer Konsole aktivieren: \pset pagerSchalten Sie die Seite aus und \xaktivieren Sie dann die erweiterte Anzeige.
Modulitos
7

Mit Paul Ramseys Hilfe habe ich es so gemacht:

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;

AKTUALISIEREN

In der Zwischenzeit habe ich eine Funktion erstellt, um nach einem bestimmten Spaltendatentyp zu fragen

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;

Die Verwendung ist:

SELECT vsr_get_data_type('schema_name.table_name','column_name')
Alexandre Neto
quelle
-1

Wenn Sie den Geometrietyp überprüfen möchten, können Sie 'udt_name' in 'INFORMATION_SCHEMA.COLUMNS' überprüfen und verwenden!:

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

Haj Hossein
quelle