Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Внешние ключи в information_schema / 5 сообщений из 5, страница 1 из 1
11.01.2009, 04:47
    #35750319
ShadyAngel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Внешние ключи в information_schema
В общем в одном приложении мне нужно получать внешние ключи в базе. Этот момент у меня реализован в виде в виде жосткого порно, с диким запросом и разбором результата через регэкспы. И тут я узнаю что есть такая вещь как 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
11.01.2009, 09:36
    #35750399
Oleg Bartunov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Внешние ключи в information_schema
ShadyAngel,

тебе поможет
\d information_schema.referential_constraints
...
Рейтинг: 0 / 0
11.01.2009, 11:32
    #35750535
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Внешние ключи в information_schema
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
12.01.2009, 03:22
    #35751677
ShadyAngel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Внешние ключи в information_schema
Ну, на самом деле я немного преувеличил, запрос у меня используется такой:
Код: 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
12.01.2009, 03:41
    #35751684
ShadyAngel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Внешние ключи в information_schema
Извините, погорячился, испугался мегазапроса из поста assa.

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


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