Получение типа данных каждого столбца из таблицы PostGIS?


9

Мне нужно получить типы данных столбцов всех столбцов в таблице, включая типы геометрии. То, что я хотел знать, есть ли функция или SQL, который дает что-то вроде этого:

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

Из нескольких ответов на stackexchange и gis.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.

Ответы:


14

Теория да, хотя вы могли бы найти это действительно сложным.

  • Каждая таблица (выберите * из pg_class) имеет столбцы.
  • Каждый столбец (выберите * из pg_attribute) может иметь номер "typmod".
  • Для типов с typmod (выберите * из pg_type) будет функция "typmodout".
  • Выполнение функции typmod out для номера typmod вернет строку, которую можно объединить с именем типа, чтобы сформировать тип читаемой пользователем подписи, к которой вы привыкли (выберите '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. Эти полигоны считаются?
Мкхеллер

7

Это можно получить с помощью простого SQL-запроса.

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


1
Это прекрасно работает! И вот совет: вывод может быть довольно длинным, поэтому вы можете включить расширенный дисплей на консоли: \pset pagerвыключить страницу, а затем \xвключить расширенный дисплей.
модуль

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

если вы хотите проверить тип геометрии, вы можете проверить 'udt_name' в 'INFORMATION_SCHEMA.COLUMNS' и использовать его !:

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.