Mendapatkan tipe data setiap kolom dari tabel PostGIS?

9

Saya perlu mendapatkan tipe data kolom dari semua kolom dalam tabel, termasuk tipe geometri. Yang ingin saya ketahui adalah apakah ada fungsi atau SQL yang memberikan sesuatu seperti ini:

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

Dari beberapa jawaban di stackexchange dan gis.stackexchange saya tahu bahwa saya bisa mendapatkan beberapa informasi dengan query berikut:

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'

Hasil:

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

Tetapi, adakah cara yang lebih praktis dan tepat untuk mengambil informasi dalam format yang saya butuhkan? Atau haruskah saya memasuki "dunia" CASE WHENstruktur dan rangkaian string untuk mengumpulkan semua atribut kolom dalam satu kolom tunggal dalam format itu?

Ketakutan saya adalah jika tipe data yang tidak diharapkan mengejutkan saya dengan memerlukan atribut lain dari tabel information_schema.columns. Yaitu, dalam tabel contoh sebelumnya, saya tidak menggunakan numeric (15,2)tipe data apa pun , yang perlu menggunakan atribut lain (numeric_precision dan numeric_scale) untuk diuraikan oleh KASUS KETIKA.

Alexandre Neto
sumber

Jawaban:

14

Teorinya ya, meskipun Anda dapat menemukannya memang sangat kompleks.

  • Setiap tabel (pilih * dari pg_class) memiliki kolom.
  • Setiap kolom (pilih * dari pg_attribute) secara opsional memiliki nomor "typmod".
  • Untuk tipe dengan typmod (pilih * dari pg_type) akan ada fungsi "typmodout".
  • Menjalankan fungsi typmod out pada nomor typmod akan mengembalikan string yang dapat digabungkan dengan nama jenis untuk membentuk jenis tanda tangan yang dapat dibaca pengguna yang Anda gunakan (pilih 'numerik' || numerictypmodout (786441)) (pilih geography_typmod_out (1107460))

Tapi, hei, psql menghasilkan string yang Anda inginkan, jika kita melihat apa yang dihasilkan SQL, mungkin jawabannya ada di sana.

Benar saja, ada fungsi ajaib yang mengambil tipus dan typmod dan mengembalikan string ajaib.

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

Dengan bergabung ke pg_class Anda harus bisa mendapatkan info ini per-tabel.

Paul Ramsey
sumber
Saya tidak mendapatkan hasil apa pun where attname = 'geog'tetapi = 'geom'berhasil. Ini memberi saya hasil yang baik untuk nilai MultiPolygon, Point dan MultiPoint tapi saya tidak melihat apa pun untuk tipe Line atau MultiLine. Apakah itu dianggap poligon?
mhkeller
7

Itu bisa menggunakan query SQL sederhana.

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

Nilesh Khode
sumber
1
Ini sangat bagus! Dan inilah tipnya: Outputnya bisa agak panjang, jadi Anda mungkin ingin mengaktifkan tampilan yang diperluas pada konsol Anda: \pset pageruntuk mematikan halaman, kemudian \xuntuk mengaktifkan tampilan yang diperluas.
modulitos
7

Dengan bantuan Paul Ramsey saya berhasil seperti ini:

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;

MEMPERBARUI

Sementara itu saya telah membuat fungsi untuk meminta tipe data kolom tertentu

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;

Penggunaannya adalah:

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

jika Anda ingin memeriksa jenis geometri, Anda dapat memeriksa 'udt_name' di 'INFORMATION_SCHEMA.COLUMNS' dan menggunakannya !:

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

Haji Hossein
sumber