web-dev-qa-db-fra.com

colonnes de requête du catalogue système postgres de la table

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?

4
as.beaulieu

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 LA GLOIRE

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                    
2
Evan Carroll