PostGISテーブルから各列のデータ型を取得していますか?


9

ジオメトリタイプを含む、テーブル内のすべての列の列データタイプを取得する必要があります。私が知りたかったのは、次のような関数またはSQLがあるかどうかです。

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

stackexchangegis.stackexchangeに関するいくつかの回答から、次のクエリでいくつかの情報を取得できることがわかります。

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'

結果:

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

しかし、必要な形式で情報を取得するための適切で実用的な方法はありますか?または、CASE WHEN構造と文字列連結の「世界」を入力して、その形式で1つの列にすべての列属性を収集する必要がありますか?

私の恐れは、予期しないデータ型がinformation_schema.columnsテーブルの他の属性を必要とすることで私を驚かせるかどうかです。つまり、前の例の表ではnumeric (15,2)、CASE WHENで解析するために別の属性(numeric_precisionおよびnumeric_scale)を使用する必要があるデータ型を使用していませんでした。

回答:


14

理論は確かに複雑です。

  • すべてのテーブル(select * from pg_class)には列があります。
  • すべての列(select * from pg_attribute)には、オプションで「typmod」番号が付いています。
  • typmodを使用するタイプ(select * from pg_type)の場合、「typmodout」関数が存在します。
  • typmod番号に対してtypmod out関数を実行すると、タイプ名と連結して、ユーザーが読み取り可能な署名の種類を形成できる文字列が返されます(select 'numeric' || numerictypmodout(786441))(select geography_typmod_out (1107460))

しかし、ちょっと、psqlは必要な文字列を生成します。生成するSQLを見ると、おそらくそこに答えがあります。

案の定、typeidとtypmodを取り、魔法の文字列を返す魔法の関数があります。

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

pg_classへの結合により、この情報をテーブルごとに取得できるはずです。


結果は得られませんwhere attname = 'geog'が、= 'geom'機能します。これにより、MultiPolygon、Point、およびMultiPointの値に良い結果が得られますが、LineまたはMultiLineタイプには何も表示されません。それらはポリゴンと見なされますか?
mhkeller 2018

7

単純なSQLクエリを使用して取得できます。

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


1
これはうまくいきます!そしてここにヒントがあります:出力は少し長くなる可能性があるので、コンソールで拡張表示を有効にすることができます:\pset pagerページをオフにして\xから、拡張表示を有効にします。
modulitos 2017年

7

ポール・ラムジーの助けを借り、私はそれをこのように作られました。

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;

更新

一方、特定の列のデータ型を要求する関数を作成しました

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;

使用法は次のとおりです。

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

-1

ジオメトリタイプを確認する場合は、「INFORMATION_SCHEMA.COLUMNS」の「udt_name」を確認して使用できます!:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.