Получение комментариев из базы данных PostgreSQL
Я запускаю проект в базе данных Postgres и должен получать комментарии к столбцам внутри БД, которые будут использоваться в качестве заголовков таблиц и т.д. Я видел, что есть несколько встроенных функций (pg_description и col_description), но я не смог найти примеры того, как их использовать, а играть с ними оказалось довольно бесполезным.
Так что мне было интересно, удалось ли кому-либо сделать это раньше, и если да, то как?
Ответы
Ответ 1
SELECT c.table_schema,c.table_name,c.column_name,pgd.description
FROM pg_catalog.pg_statio_all_tables as st
inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid)
inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position
and c.table_schema=st.schemaname and c.table_name=st.relname);
Ответ 2
Все работает с помощью oid,
mat=> SELECT c.oid FROM pg_catalog.pg_class c WHERE c.relname = 'customers';
oid
-------
23208
(1 row)
Теперь у меня есть oid для этой таблицы, поэтому я могу спросить:
mat=> select pg_catalog.obj_description(23208);
obj_description
-------------------
Customers
(1 row)
Затем я могу попросить описание четвертого столбца:
mat=> select pg_catalog.col_description(23208,4);
col_description
-----------------------------------------
Customer codes, CHS, FACTPOST, POWER...
(1 row)
Если вы хотите узнать, какие запросы psql
выполняются, когда вы делаете \dt+
или \d+ customers
, просто запустите его с помощью -E
.
Ответ 3
Соблюдайте схемы, этот код учитывает их:
SELECT
cols.column_name,
(
SELECT
pg_catalog.col_description(c.oid, cols.ordinal_position::int)
FROM
pg_catalog.pg_class c
WHERE
c.oid = (SELECT ('"' || cols.table_name || '"')::regclass::oid)
AND c.relname = cols.table_name
) AS column_comment
FROM
information_schema.columns cols
WHERE
cols.table_catalog = 'your_database'
AND cols.table_name = 'your_table'
AND cols.table_schema = 'your_schema';
Литература:
Ответ 4
Это работает для меня с помощью PostBooks 3.2.2 DB:
select cols.column_name,
(select pg_catalog.obj_description(oid) from pg_catalog.pg_class c where c.relname=cols.table_name) as table_comment
,(select pg_catalog.col_description(oid,cols.ordinal_position::int) from pg_catalog.pg_class c where c.relname=cols.table_name) as column_comment
from information_schema.columns cols
where cols.table_catalog='postbooks' and cols.table_name='apapply'
С уважением,
Sylnsr
Ответ 5
Улучшение для @Nick и @mat предложений: использование
SELECT obj_description('schemaName.tableName'::regclass, 'pg_class');
когда у вас есть имя строки (не oid).
Чтобы не помнить параметр "pg_class" и избегать уродливых конкатенаций при вызове функций, как (tname||'.'||schema)::regclass
, полезная перегрузка для obj_description
:
CREATE FUNCTION obj_description(
p_rname text, p_schema text DEFAULT NULL,
p_catalname text DEFAULT 'pg_class'
) RETURNS text AS $f$
SELECT obj_description((CASE
WHEN strpos($1, '.')>0 OR $2 IS NULL OR $2='' THEN $1
ELSE $2||'.'||$1
END)::regclass, $3);
$f$ LANGUAGE SQL IMMUTABLE;
-- USAGE: obj_description('mytable')
-- SELECT obj_description('s.t');
-- PS: obj_description('s.t', 'otherschema') is a syntax error,
-- but not generates exception: returns the same as ('s.t')
Теперь он прост в использовании, поскольку имя таблицы (rname
) является varchar и может быть выражено разделенным полем для имени схемы, как в основных таблицах и запросах.
См. также Получение списка комментариев к таблице в PostgreSQL "или new pg9.3 Руководство
Ответ 6
Просто, чтобы быть здесь, если кому-то это понадобится.
Здесь много ответов, но ни один из них не был таким простым, как хотелось бы. Итак, на основе предыдущих ответов и текущих postgres 9.4, я создал этот запрос:
SELECT
obj_description(format('%s.%s',isc.table_schema,isc.table_name)::regclass::oid, 'pg_class') as table_description,
pg_catalog.col_description(format('%s.%s',isc.table_schema,isc.table_name)::regclass::oid,isc.ordinal_position) as column_description
FROM
information_schema.columns isc
Он извлекает описания таблиц и столбцов без каких-либо запутывающих объединений и уродливых конкатенаций строк.
Ответ 7
Хорошо, поэтому я отработал его до степени...
выберите col_description (идентификатор таблицы, номер столбца)...
ie: select col_description (36698,2);
Это сработало, но есть ли более простой способ сделать это, возможно, принеся все комментарии ко всем столбцам и используя имя таблицы вместо oid???
Ответ 8
Прохладный, это работает, чтобы вывести один комментарий, но есть ли способ вывести все комментарии из всех столбцов без нескольких операторов select или цикла?
И как вы запускаете это с помощью инструкции:
Если вы хотите узнать, какие запросы выполняются psql, когда вы делаете \dt + или \d + клиентов, просто запустите его с помощью -E.
Спасибо
Ответ 9
Я спросил аналогичный вопрос о комментариях Postgresql в прошлом месяце. Если вы выкапываете это, вы столкнетесь с некоторым кодом Perl в моем блоге, который автоматизирует процесс извлечения комментария.
Чтобы вывести имена столбцов таблицы, вы можете использовать что-то вроде следующего:
select
a.attname as "colname"
,a.attrelid as "tableoid"
,a.attnum as "columnoid"
from
pg_catalog.pg_attribute a
inner join pg_catalog.pg_class c on a.attrelid = c.oid
where
c.relname = 'mytable' -- better to use a placeholder
and a.attnum > 0
and a.attisdropped is false
and pg_catalog.pg_table_is_visible(c.oid)
order by a.attnum
Затем вы можете использовать tableoid, columnoid tuple, чтобы извлечь комментарий для каждого столбца (см. мой вопрос).
Ответ 10
Этот ответ немного запоздал, но он появился в поисковой системе Google, которую я сделал, чтобы исследовать эту проблему. Нам нужны только описания таблиц, но метод будет одинаковым для столбцов.
Описания столбцов также находятся в таблице pg_description, на которые ссылается objoid.
Добавьте этот вид:
CREATE OR REPLACE VIEW our_tables AS
SELECT c.oid, n.nspname AS schemaname, c.relname AS tablename, d.description,
pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace",
c.relhasindex AS hasindexes, c.relhasrules AS hasrules, c.reltriggers > 0 AS hastriggers
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_tablespace t ON t.oid = c.reltablespace
LEFT JOIN pg_description d ON c.oid = d.objoid
WHERE c.relkind = 'r'::"char";
ALTER TABLE our_tables OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE, REFERENCES, TRIGGER ON TABLE our_tables TO postgres;
GRANT SELECT ON TABLE our_tables TO public;
Затем запустите:
SELECT tablename, description FROM our_tables WHERE schemaname = 'public'
Представление представляет собой модифицированную версию представления pg_tables, которая добавляется в столбец описания.
Вы также можете обезопасить себя с определением вида, чтобы сделать его одним запросом.
Ответ 11
Я только что нашел это здесь. Он предоставит вам все виды метаданных в одной конкретной таблице (тип, значение по умолчанию, а не нулевой флаг, длина, комментарий, имя внешнего ключа, имя первичного ключа). Кажется, что он работает хорошо.
SELECT pg_tables.tablename, pg_attribute.attname AS field,
format_type(pg_attribute.atttypid, NULL) AS "type",
pg_attribute.atttypmod AS len,
(SELECT col_description(pg_attribute.attrelid,
pg_attribute.attnum)) AS comment,
CASE pg_attribute.attnotnull
WHEN false THEN 1 ELSE 0
END AS "notnull",
pg_constraint.conname AS "key", pc2.conname AS ckey,
(SELECT pg_attrdef.adsrc FROM pg_attrdef
WHERE pg_attrdef.adrelid = pg_class.oid
AND pg_attrdef.adnum = pg_attribute.attnum) AS def
FROM pg_tables, pg_class
JOIN pg_attribute ON pg_class.oid = pg_attribute.attrelid
AND pg_attribute.attnum > 0
LEFT JOIN pg_constraint ON pg_constraint.contype = 'p'::"char"
AND pg_constraint.conrelid = pg_class.oid AND
(pg_attribute.attnum = ANY (pg_constraint.conkey))
LEFT JOIN pg_constraint AS pc2 ON pc2.contype = 'f'::"char"
AND pc2.conrelid = pg_class.oid
AND (pg_attribute.attnum = ANY (pc2.conkey))
WHERE pg_class.relname = pg_tables.tablename
-- AND pg_tables.tableowner = "current_user"()
AND pg_attribute.atttypid <> 0::oid
AND tablename='your_table'
ORDER BY field ASC
Источник: http://golden13.blogspot.de/2012/08/how-to-get-some-information-about_7.html
Ответ 12
Я получил доступ к табличным комментариям следующим образом:
select c.relname table_name, pg_catalog.obj_description(c.oid) as comment from pg_catalog.pg_class c where c.relname = 'table_name';
и комментарии столбца:
SELECT c.column_name, pgd.description FROM pg_catalog.pg_statio_all_tables as st inner join pg_catalog.pg_description pgd on (pgd.objoid=st.relid) inner join information_schema.columns c on (pgd.objsubid=c.ordinal_position and c.table_schema=st.schemaname and c.table_name=st.relname and c.table_name = 'table_name' and c.table_schema = 'public');