从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结构和字符串串联的“世界”,以该格式将所有列属性收集到一个列中?

我担心的是,如果非预期的数据类型需要来自information_schema.columns表中的其他属性,会使我感到惊讶。也就是说,在之前的示例表中,我没有使用任何numeric (15,2)数据类型,而将需要使用另一个属性(numeric_precision和numeric_scale)来由CASE WHEN进行解析。

Answers:


14

该理论是的,尽管您确实会发现它非常复杂。

  • 每个表(从pg_class中选择*)都有列。
  • 每列(从pg_attribute中选择*)可选地具有“ typmod”数字。
  • 对于具有typmod的类型(从pg_type中选择*),将有一个“ typmodout”函数。
  • 在typmod数字上运行typmod out函数将返回一个字符串,该字符串可以与类型名称连接起来以形成您习惯的用户可读签名的类型(选择'numeric'|| numerictypmodout(786441))(选择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

7

可以使用简单的SQL查询获得。

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


1
这很棒!这里有个提示:输出可能会很长,因此您可能需要在控制台上启用扩展显示:\pset pager关闭页面,然后\x启用扩展显示。
modulitos

7

Paul Ramsey的帮助下,我做到了:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.