Je crée un test d'intégration par rapport à une application qui provisionne une base de données pour un utilisateur. L'utilisateur créé pour lui n'est pas un super utilisateur et ne le fait pas a accès à schema_information.tables parce que lorsque j'essaie le script suivant:
SELECT table_name
FROM information_schema.tables
WHERE table_schema='{schema}'
J'obtiens un retour de 0, comme je le devrais puisque cet utilisateur n'a pas la permission.
J'essaie d'interroger la base de données pour vérifier les tables et les colonnes créées. Je peux obtenir la liste des noms de table via le catalogue système avec le script suivant:
SELECT tablename
FROM pg_catalog.pg_tables
WHERE schemaname = '{schema}'
Et cela génère le nom de la table comme je le veux:
entreprise, emplacement, personne, etc ...
Je ne trouve pas le script avec le catalogue système pour trouver ensuite les noms des colonnes (Et en bonus, le type de données) de chaque table. Jusqu'à présent, j'ai essayé ce qui suit:
SELECT attname, format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE attrelid = 'business'
et voici l'erreur:
ERROR: invalid input syntax for type oid: "business"
LINE 1: ...od) AS type FROM pg_attribute WHERE attrelid = 'business'
^```
A également essayé:
SELECT
a.attname as "Column",
pg_catalog.format_type(a.atttypid, a.atttypmod) as "Datatype"
FROM
pg_catalog.pg_attribute a
WHERE
a.attnum > 0
AND NOT a.attisdropped
AND a.attrelid = (
SELECT c.oid
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ~ '**Dont know what to put here, Schema? Database?**'
--AND pg_catalog.pg_table_is_visible(c.oid)
);
et cela renvoie 0 avec un schéma ou une base de données. Je ne sais pas quoi mettre là pour c.relname. Suis-je également voir 0 avec cela parce qu'un utilisateur de base ne peut tout simplement pas voir plus profondément que les tables dans un schéma, point?
Sélectionnez simplement parmi information_schema.columns
à la place.
SELECT table_catalog, table_schema, table_name, data_type
FROM information_schema.tables
WHERE table_schema='{schema}';
Pour une raison quelconque, si vous ne pouvez pas interroger information_schema.columns
(ce qui, autrement, indiquerait que quelque chose est génial pour moi). Nous pouvons effectuer une rétro-ingénierie efficace des catalogues avec psql -E
avec un utilisateur qui le peut. Exécutez ensuite le client approprié (\
) dans psql
qui vous montre ce que vous voulez, comme \d schema
. Et copiez les parties de la requête exportée dont vous avez besoin.
Pour moi, la dernière colonne est quelque chose comme
SELECT a.attname,
pg_catalog.format_type(a.atttypid, a.atttypmod),
(SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),
a.attnotnull, a.attnum,
(SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t
WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation,
NULL AS indexdef,
NULL AS attfdwoptions
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = '1024334' AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;
Maintenant, j'ai juste besoin d'obtenir tous les attrelid
pour le schéma. Exécuter un rapide \d asdofkodskf
Je vois,
SELECT c.oid,
n.nspname,
c.relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ~ '^(asdofkodskf)$'
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2, 3;
Nous voulons en fait n.nspname
ne pas c.relname
Donc, étant donné ma version de psql
, la méthode officielle d'interrogation directe du catalogue serait ...
SELECT c.oid,
n.nspname,
c.relname, t.*
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
CROSS JOIN LATERAL (
SELECT a.attname,
pg_catalog.format_type(a.atttypid, a.atttypmod),
(
SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid
AND d.adnum = a.attnum
AND a.atthasdef
),
a.attnotnull, a.attnum,
(
SELECT c.collname
FROM
pg_catalog.pg_collation c,
pg_catalog.pg_type t
WHERE c.oid = a.attcollation
AND t.oid = a.atttypid
AND a.attcollation <> t.typcollation
) AS attcollation
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = c.oid
AND a.attnum > 0
AND NOT a.attisdropped
) AS t
WHERE n.nspname ~ '^(public)$' -- YOUR SCHEMA HERE
AND pg_catalog.pg_table_is_visible(c.oid);
Extrait (sans toutes les colonnes ou toutes les lignes) (relname est table, attname est colonne)
oid | nspname | relname | attname | format_type
llation
---------+---------+-----------------------------+----------------------+-------------------------
--------
1024242 | public | spatial_ref_sys_pkey | srid | integer
1045853 | public | product_discount_qty_excl | qty | int4range
1024334 | public | valid_detail | valid | boolean
1024334 | public | valid_detail | reason | character varying
1024334 | public | valid_detail | location | geometry
1045847 | public | product_discount | pid | integer
1045847 | public | product_discount | qty | int4range
1045847 | public | product_discount | percent_modifier | real
1024569 | public | geography_columns | f_table_catalog | name