web-dev-qa-db-fra.com

Afficher les types définis par l'utilisateur et leurs détails

J'ai créé quelques nouveaux UDT dans PostgreSQL. Cependant, maintenant j'ai deux problèmes:

  1. comment voir quels UDT ont été définis?
  2. comment voir les colonnes définies dans ces UDT?

Malheureusement, je n'ai rien trouvé à ce sujet dans la documentation PostgreSQL.

12
navige

Cela vous permet-il de commencer?

SELECT n.nspname AS schema,
        pg_catalog.format_type ( t.oid, NULL ) AS name,
        t.typname AS internal_name,
        CASE
            WHEN t.typrelid != 0
            THEN CAST ( 'Tuple' AS pg_catalog.text )
            WHEN t.typlen < 0
            THEN CAST ( 'var' AS pg_catalog.text )
            ELSE CAST ( t.typlen AS pg_catalog.text )
        END AS size,
        pg_catalog.array_to_string (
            ARRAY( SELECT e.enumlabel
                    FROM pg_catalog.pg_enum e
                    WHERE e.enumtypid = t.oid
                    ORDER BY e.oid ), E'\n'
            ) AS elements,
        pg_catalog.obj_description ( t.oid, 'pg_type' ) AS description
    FROM pg_catalog.pg_type t
    LEFT JOIN pg_catalog.pg_namespace n
        ON n.oid = t.typnamespace
    WHERE ( t.typrelid = 0
            OR ( SELECT c.relkind = 'c'
                    FROM pg_catalog.pg_class c
                    WHERE c.oid = t.typrelid
                )
        )
        AND NOT EXISTS
            ( SELECT 1
                FROM pg_catalog.pg_type el
                WHERE el.oid = t.typelem
                    AND el.typarray = t.oid
            )
        AND n.nspname <> 'pg_catalog'
        AND n.nspname <> 'information_schema'
        AND pg_catalog.pg_type_is_visible ( t.oid )
    ORDER BY 1, 2;

Dans psql, vous pouvez \set ECHO_HIDDEN on pour que psql vous montre les requêtes utilisées pour générer la sortie du \d... commandes. J'ai trouvé ces requêtes très utiles comme point de départ pour extraire des métadonnées de bases de données.

Mise à jour: 2019-12-16

Pour les types composites, les métadonnées des colonnes peuvent être déterminées en utilisant quelque chose comme ce qui suit:

WITH types AS (
    SELECT n.nspname,
            pg_catalog.format_type ( t.oid, NULL ) AS obj_name,
            CASE
                WHEN t.typrelid != 0 THEN CAST ( 'Tuple' AS pg_catalog.text )
                WHEN t.typlen < 0 THEN CAST ( 'var' AS pg_catalog.text )
                ELSE CAST ( t.typlen AS pg_catalog.text )
                END AS obj_type,
            coalesce ( pg_catalog.obj_description ( t.oid, 'pg_type' ), '' ) AS description
        FROM pg_catalog.pg_type t
        JOIN pg_catalog.pg_namespace n
            ON n.oid = t.typnamespace
        WHERE ( t.typrelid = 0
                OR ( SELECT c.relkind = 'c'
                        FROM pg_catalog.pg_class c
                        WHERE c.oid = t.typrelid ) )
            AND NOT EXISTS (
                    SELECT 1
                        FROM pg_catalog.pg_type el
                        WHERE el.oid = t.typelem
                        AND el.typarray = t.oid )
            AND n.nspname <> 'pg_catalog'
            AND n.nspname <> 'information_schema'
            AND n.nspname !~ '^pg_toast'
),
cols AS (
    SELECT n.nspname::text AS schema_name,
            pg_catalog.format_type ( t.oid, NULL ) AS obj_name,
            a.attname::text AS column_name,
            pg_catalog.format_type ( a.atttypid, a.atttypmod ) AS data_type,
            a.attnotnull AS is_required,
            a.attnum AS ordinal_position,
            pg_catalog.col_description ( a.attrelid, a.attnum ) AS description
        FROM pg_catalog.pg_attribute a
        JOIN pg_catalog.pg_type t
            ON a.attrelid = t.typrelid
        JOIN pg_catalog.pg_namespace n
            ON ( n.oid = t.typnamespace )
        JOIN types
            ON ( types.nspname = n.nspname
                AND types.obj_name = pg_catalog.format_type ( t.oid, NULL ) )
        WHERE a.attnum > 0
            AND NOT a.attisdropped
)
SELECT cols.schema_name,
        cols.obj_name,
        cols.column_name,
        cols.data_type,
        cols.ordinal_position,
        cols.is_required,
        coalesce ( cols.description, '' ) AS description
    FROM cols
    ORDER BY cols.schema_name,
            cols.obj_name,
            cols.ordinal_position ;
16
gsiems

Vous pouvez utiliser l'interface graphique standard pgAdmin :

types in pgAdmin

Assurez-vous que les types sont activés dans le navigateur d'objets (Options - Navigateur - Affichage)

À gauche, vous voyez les types définis par l'utilisateur dans le schéma choisi (question 1. ).

Le SQL pane à droite a le script SQL reverse engineering pour le type sélectionné (question 2. ).
Plus de détails dans le volet ci-dessus, comme Dependents etc.


Vous pouvez également utiliser la console interactive standard psql:

  1. \dT pour obtenir une liste des types définis par l'utilisateur.
  2. \d type_name pour obtenir la liste des définitions de colonnes pour le type donné.

Le manuel:

\d[S+] [ pattern ]

Pour chaque relation (table, vue, vue matérialisée, index, séquence ou table étrangère) ou type composite correspondant au modèle , afficher toutes les colonnes, leurs types, [...]

Accentuation sur moi. La commande fonctionne également pour les types composites depuis au moins Postgres 9.1.

Et:

\dT[S+] [ pattern ]

Répertorie les types de données. Si le modèle est spécifié, seuls les types dont les noms correspondent au modèle sont répertoriés. Si + est ajouté au nom de la commande, chaque type est répertorié avec son nom et sa taille internes, ses valeurs autorisées s'il s'agit d'un type enum et ses autorisations associées. Par défaut, seuls les objets créés par l'utilisateur sont affichés; fournissez un modèle ou le modificateur S pour inclure les objets système.

13
Erwin Brandstetter

Ceci est une alternative très simple, mais suffisant pour des cas d'utilisation simples. Lorsque le type de la colonne est UDT, nous utilisons le udt_name colonne de information_schema.columns table.

select column_name, case 
        when (data_type = 'USER-DEFINED') then udt_name 
        else data_type 
    end as data_type
from information_schema.columns 
where table_schema = 'altimetria' and table_name = 'cnivel';

Résultat (geometryest un UDT):

 column_name  |    data_type     
--------------+------------------
 ogc_fid      | integer
 wkb_geometry | geometry
 id_cnivel    | bigint
 cod_cart     | bigint
 cod_fam      | bigint
 cod_sub      | integer
 z            | double precision
 shape_len    | double precision
1
jgrocha

Essayez d'exécuter ce code:

SELECT
    pg_type.typname, 
     pg_enum.enumlabel
FROM
    pg_type 
JOIN
    pg_enum ON pg_enum.enumtypid = pg_type.oid;
1
Santos L. Victor