Dois-je être propriétaire de la relation avec les données liées aux contraintes d'accès dans le schéma d'information? J'ai testé les éléments suivants et il semble que je dois en être le propriétaire.
create schema rights_test;
create table rights_test.t1 (id int primary key);
create table rights_test.t2 (id int references rights_test.t1(id));
select
tc.constraint_name,
tc.constraint_schema || '.' || tc.table_name || '.' || kcu.column_name as physical_full_name,
tc.constraint_schema,
tc.table_name,
kcu.column_name,
ccu.table_name as foreign_table_name,
ccu.column_name as foreign_column_name,
tc.constraint_type
from
information_schema.table_constraints as tc
join information_schema.key_column_usage as kcu on (tc.constraint_name = kcu.constraint_name and tc.table_name = kcu.table_name)
join information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name
where
constraint_type in ('PRIMARY KEY','FOREIGN KEY')
and tc.constraint_schema = 'rights_test'
/*
This will produce desired output:
t1_pkey;rights_test.t1.id;rights_test;t1;id;t1;id;PRIMARY KEY
t2_id_fkey;rights_test.t2.id;rights_test;t2;id;t1;id;FOREIGN KEY
*/
create user rights_test_role with password 'password';
grant all on rights_test.t1 to rights_test_role;
grant all on rights_test.t2 to rights_test_role;
/* Now login as rights_test_role and try the same constraint select.
For rights_test_role it returns nothing although I've added ALL privileges
*/
Existe-t-il un autre moyen d'obtenir la même information si je ne suis pas propriétaire de la relation?
Toutes les données liées aux contraintes ne sont pas "protégées". Vous utilisez trois relations dans votre requête:
table_constraints
key_column_usage
constraint_column_usage
Les deux premiers ne sont pas limités, mais la documentation de constraint_column_usage
vous indique:
La vue constraint_column_usage identifie toutes les colonnes de la base de données actuelle utilisées par une contrainte. Seules les colonnes indiquées sont contenues dans une table appartenant à un rôle actuellement activé.
information_schema.constraint_column_usage
étant une vue, vous pouvez voir sa définition en utilisant
\d+ information_schema.constraint_column_usage
dans le shell psql. Le résultat semble effrayant au premier abord, mais ce n'est pas si grave. La chose la plus intéressante - pour un premier test - est la partie de la dernière ligne:
WHERE pg_has_role(x.tblowner, 'USAGE'::text);
Si vous collez la définition dans le shell psql ouvert par le non-propriétaire rights_test_role
et supprimez cette dernière ligne, vous obtiendrez le résultat souhaité. C’est bien, car cela signifie que les métadonnées de base ne sont pas protégées par le système. Vous pouvez donc supprimer la définition de vue pour n’inclure que les éléments dont vous avez réellement besoin.
Essayez d'utiliser ceci .. donne tous les noms de contrainte et description de contrainte.
Comme:
select conrelid::regclass AS table_from, conname, pg_get_constraintdef(c.oid)
from pg_constraint c
join pg_namespace n ON n.oid = c.connamespace
where contype in ('f', 'p','c','u') order by contype
Pour lister les contraintes relationnelles, vous pouvez utiliser la requête suivante:
SELECT
tc.constraint_name, tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY'