powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Внешние ключи в information_schema
5 сообщений из 5, страница 1 из 1
Внешние ключи в information_schema
    #35750319
ShadyAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем в одном приложении мне нужно получать внешние ключи в базе. Этот момент у меня реализован в виде в виде жосткого порно, с диким запросом и разбором результата через регэкспы. И тут я узнаю что есть такая вещь как information_schema, которая во первых реализует стандарт, а во вторых данные там в более удобоваримом виде. Прочитал доки:
http://www.postgresql.org/docs/current/interactive/information-schema.html
http://www.postgresql.org/docs/current/interactive/infoschema-referential-constraints.html

Проверил, запрос
Код: plaintext
select * from information_schema.referential_constraints

Действительно работает. То есть выводит все внешние ключи.

Но при этом выводит так что непонятно, какое поле из какой таблицы на что ссылается.
Можно как нибудь используя information_schema получить всю информацию о внешних ключах?
...
Рейтинг: 0 / 0
Внешние ключи в information_schema
    #35750399
Oleg Bartunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShadyAngel,

тебе поможет
\d information_schema.referential_constraints
...
Рейтинг: 0 / 0
Внешние ключи в information_schema
    #35750535
assa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShadyAngel Можно как нибудь используя information_schema получить всю информацию о внешних ключах?наверное можно: например получив тексты вьюшек этой схемы собрать свою.
так например читая вьюшку
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
--малек покурочил, чтобы почитабельнее
-- View: "information_schema.constraint_column_usage"
/*CREATE OR REPLACE VIEW information_schema.constraint_column_usage AS */
 SELECT current_database()::information_schema.sql_identifier AS table_catalog
, x.tblschema::information_schema.sql_identifier AS table_schema
, x.tblname::information_schema.sql_identifier AS table_name
, x.colname::information_schema.sql_identifier AS column_name
, current_database()::information_schema.sql_identifier AS constraint_catalog
, x.cstrschema::information_schema.sql_identifier AS constraint_schema
, x.cstrname::information_schema.sql_identifier AS constraint_name
/*йа*/, contype
   FROM (
/*( SELECT DISTINCT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
           FROM pg_namespace nr, pg_class r, pg_attribute a, pg_depend d, pg_namespace nc, pg_constraint c
          WHERE nr.oid = r.relnamespace
		AND r.oid = a.attrelid
		AND d.refclassid = 'pg_class'::regclass::oid
		AND d.refobjid = r.oid 
		AND d.refobjsubid = a.attnum
		AND d.classid = 'pg_constraint'::regclass::oid
		AND d.objid = c.oid
		AND c.connamespace = nc.oid
		AND c.contype = 'c'::"char"
		AND r.relkind = 'r'::"char"
		AND NOT a.attisdropped
          ORDER BY nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname)
	UNION ALL 
*/
         SELECT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
/*йа*/,c.contype
           FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc, pg_constraint c
          WHERE nr.oid = r.relnamespace
		AND r.oid = a.attrelid
		AND nc.oid = c.connamespace
		AND 
                CASE
                    WHEN c.contype = 'f'::"char" THEN r.oid = c.confrelid AND (a.attnum = ANY (c.confkey))
                    ELSE r.oid = c.conrelid AND (a.attnum = ANY (c.conkey))
                END
		AND NOT a.attisdropped
		AND (c.contype = ANY (ARRAY['p'::"char", 'u'::"char", 'f'::"char"])		)
		AND r.relkind = 'r'::"char"
/*1*/
)
 AS x(tblschema, tblname, tblowner, colname, cstrschema, cstrname
/*йа*/,contype)
 WHERE pg_has_role(x.tblowner, 'USAGE'::text)
/*йа*/ AND contype = 'f';

можно заметить, что все что требуется лежит в табличке
pg_constraint, по условию contype = 'f', причем, если взглянуть в саму pg_constraint, заметим, что мастер табличку надо искать через поле confrelid, в табличке pg_class, а подчиненную - через conrelid.

как прикрутить еще одну pg_attribute для получения имени головных столбцов - видимо как в пример выше (см) через поля- массивы confkey/conkey
Код: plaintext
1.
2.
(a.attnum = ANY (c.confkey))
--по аналогии:
(a1.attnum = ANY (c1.conkey))
надо полагать, что соответствие полей при многополевой связи идет по позициям полей в этих массивах. где поле attnum - видимо типа номера поля в таблицах.
...
Рейтинг: 0 / 0
Внешние ключи в information_schema
    #35751677
ShadyAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, на самом деле я немного преувеличил, запрос у меня используется такой:
Код: plaintext
1.
SELECT pg_catalog.pg_get_constraintdef(r.oid, true) as condef 	FROM pg_catalog.pg_constraint r, pg_class c 
	WHERE r.conrelid = c.oid AND r.contype = 'f' AND c.relname='{$this->tablename}' ORDER BY  1 

Основная проблема что он выдает не таблицу, а строки, в которых все данные есть, но их приходится выкусывать регэкспом. Я думал что этот момент можно как то упростить и стандартизировать, но видимо лучше не связываться, всё равно проще не получится.
...
Рейтинг: 0 / 0
Внешние ключи в information_schema
    #35751684
ShadyAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извините, погорячился, испугался мегазапроса из поста assa.

Действительно если сделать select * from pg_constraint то там почти все интуитивно понятно.
Спасибо всем :)
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Внешние ключи в information_schema
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]