

Lorsqu'une table est créée et qu'une erreur a été commise ou que les besoins de l'application changent, il est alors possible de la supprimer et de la récréer. Cela n'est toutefois pas pratique si la table contient déjà des données ou qu'elle est référencée par d'autres objets de la base de données (une contrainte de clé étrangère, par exemple). C'est pourquoi PostgreSQL offre une série de commandes permettant de modifier une table existante. Cela n'a rien à voir avec la modification des données contenues dans la table ; il ne s'agit ici que de modifier la définition, ou structure, de la table.
Il est possible :
d'ajouter des colonnes ;
de supprimer des colonnes ;
d'ajouter des contraintes ;
de supprimer des contraintes ;
de modifier des valeurs par défaut ;
de modifier les types de données des colonnes ;
de renommer des colonnes ;
de renommer des tables.
Toutes ces actions sont réalisées à l'aide de la commande ALTER TABLE, dont la page de référence est bien plus détaillée.
La commande d'ajout d'une colonne ressemble à :
ALTER TABLE produits ADD COLUMN description text;
    La nouvelle colonne est initialement remplie avec la valeur par défaut
    précisée (NULL en l'absence de clause DEFAULT).
   
     À partir de PostgreSQL 11, ajouter une colonne
     avec une valeur par défaut constante ne signifie plus que chaque ligne
     de la table doit être mise à jour quand l'instruction ALTER
     TABLE doit être exécutée. À la place, la valeur par défaut
     sera renvoyée à chaque accès à la ligne et appliquée quand la table est
     réécrite, rendant ainsi la commande ALTER TABLE bien
     plus rapide, même sur des tables volumineuses.
    
     Néanmoins, si la valeur par défaut est volatile (par exemple
     clock_timestamp()), chaque ligne devra être mise à
     jour avec la valeur calculée à l'exécution du ALTER
     TABLE. Pour éviter une opération de mise à jour
     potentiellement longue, et en particulier si vous avez de toute façon
     l'intention de remplir la colonne avec des valeurs qui ne sont pas par
     défaut, il pourrait être préférable d'ajouter la colonne sans valeur par
     défaut, d'insérer les valeurs correctes en utilisant l'instruction
     UPDATE, et enfin d'ajouter la valeur par désirée
     comme décrit ci-dessous.
    
Des contraintes de colonne peuvent être définies dans la même commande, à l'aide de la syntaxe habituelle :
ALTER TABLE produits ADD COLUMN description text CHECK (description <> '');
    En fait, toutes les options applicables à la description d'une colonne
    dans CREATE TABLE peuvent être utilisées ici. Il ne
    faut toutefois pas oublier que la valeur par défaut doit satisfaire les
    contraintes données. Dans le cas contraire, ADD
    échoue. Il est aussi possible d'ajouter les contraintes ultérieurement
    (voir ci-dessous) après avoir rempli la nouvelle colonne correctement.
   
La commande de suppression d'une colonne ressemble à celle-ci :
ALTER TABLE produits DROP COLUMN description;
    Toute donnée dans cette colonne disparaît. Les contraintes de table
    impliquant la colonne sont également supprimées. Néanmoins, si la colonne
    est référencée par une contrainte de clé étrangère d'une autre table,
    PostgreSQL ne supprime pas silencieusement
    cette contrainte. La suppression de tout ce qui dépend de la colonne peut
    être autorisée en ajoutant CASCADE :
    
ALTER TABLE produits DROP COLUMN description CASCADE;
Voir la Section 5.14 pour une description du mécanisme général.
     PostgreSQL ne supporte pas les contraintes
     CHECK qui référencent les données d'autres tables que
     celle contenant la nouvelle ligne ou la ligne mise à jour en cours de
     vérification. Alors qu'une contrainte CHECK qui viole
     cette règle pourrait apparaitre fonctionner dans des tests simples, il
     est possible que la base de données atteigne un état dans lequel la
     condition de la contrainte est fausse (à cause de changements
     supplémentaires en dehors de la ligne impliquée). Ceci sera la cause
     d'un échec du rechargement de la sauvegarde d'une base. La restauration
     pourrait échouer même quand l'état complet de la base est cohérent avec
     la contrainte, à cause de lignes chargées dans un autre différent qui
     satisferait la contrainte. Si possible, utilisez les contraintes
     UNIQUE, EXCLUDE, et
     FOREIGN KEY pour exprimer des restrictions
     inter-lignes et inter-tables.
    
Si ce que vous désirez est une vérification unique avec certaines lignes au moment de l'insertion, plutôt qu'une garantie de cohérence maintenue en permanence, un trigger personnalisé peut être utilisé pour l'implémenter. (Cette approche évite le problème de sauvegarde/restauration car pg_dump ne réinstalle les triggers qu'après chargement des données, donc cette vérification ne sera pas effectuée pendant une sauvegarde/restauration.)
     PostgreSQL suppose que les conditions des
     contraintes CHECK sont immutables, c'est-à-dire
     qu'elles donneront toujours le même résultat pour la même ligne en
     entrée. Cette supposition est ce qui justifie l'examen des contraintes
     CHECK uniquement quand les lignes sont insérées ou
     mises à jour, et non pas à d'autres moments. (Cet avertissement sur la
     non référence aux données d'autres tables est en fait un cas particulier
     de cette restriction.)
    
     Un exemple d'une façon habituelle de casser cette supposition est de
     référencer une fonction utilisateur dans une expression
     CHECK, puis de changer le comportement de cette
     fonction. PostgreSQL n'interdit pas cela,
     mais il ne notera pas qu'il y a des lignes dans la table qui violent
     maintenant la contrainte CHECK. Ceci sera la cause
     d'un échec de la restauration d'une sauvegarde de cette base. La façon
     recommandée de gérer de tels changements revient à supprimer la
     contrainte (en utilisant ALTER TABLE), d'ajuster la
     définition de la fonction, et d'ajouter de nouveau la contrainte, ce qui
     causera une nouvelle vérification des lignes de la table.
    
Pour ajouter une contrainte, la syntaxe de contrainte de table est utilisée. Par exemple :
ALTER TABLE produits ADD CHECK (nom <> ''); ALTER TABLE produits ADD CONSTRAINT autre_nom UNIQUE (no_produit); ALTER TABLE produits ADD FOREIGN KEY (id_groupe_produit) REFERENCES groupes_produits;
Pour ajouter une contrainte NOT NULL, qui ne peut pas être écrite sous forme d'une contrainte de table, la syntaxe suivante est utilisée :
ALTER TABLE produits ALTER COLUMN no_produit SET NOT NULL;
La contrainte étant immédiatement vérifiée, les données de la table doivent satisfaire la contrainte avant qu'elle ne soit ajoutée.
    Pour supprimer une contrainte, il faut connaître son nom. Si elle a été
    explicitement nommée, il n'y a aucune difficulté. Dans le cas contraire,
    le système a affecté un nom généré qu'il faudra identifier. La commande
    \d  de
    psql peut être utile ici ; d'autres
    interfaces offrent aussi la possibilité d'examiner les détails de table.
    La commande est :
    table
ALTER TABLE produits DROP CONSTRAINT un_nom;
    Comme pour la suppression d'une colonne, CASCADE peut
    être ajouté pour supprimer une contrainte dont dépendent d'autres objets.
    Une contrainte de clé étrangère, par exemple, dépend d'une contrainte de
    clé primaire ou d'unicité sur la(les) colonne(s) référencée(s).
   
Cela fonctionne de la même manière pour tous les types de contraintes, à l'exception des contraintes NOT NULL. Pour supprimer une contrainte NOT NULL, on écrit :
ALTER TABLE produits ALTER COLUMN no_produit DROP NOT NULL;
(Les contraintes NOT NULL n'ont pas de noms.)
La commande de définition d'une nouvelle valeur par défaut de colonne ressemble à celle-ci :
ALTER TABLE produits ALTER COLUMN prix SET DEFAULT 7.77;
    Cela n'affecte pas les lignes existantes de la table, mais uniquement la
    valeur par défaut pour les futures commandes INSERT.
   
Pour retirer toute valeur par défaut, on écrit :
ALTER TABLE produits ALTER COLUMN prix DROP DEFAULT;
C'est équivalent à mettre la valeur par défaut à NULL. En conséquence, il n'y a pas d'erreur à retirer une valeur par défaut qui n'a pas été définie car NULL est la valeur par défaut implicite.
La commande de conversion du type de données d'une colonne ressemble à celle-ci :
ALTER TABLE produits ALTER COLUMN prix TYPE numeric(10,2);
    Elle ne peut réussir que si chaque valeur de la colonne peut être
    convertie dans le nouveau type par une conversion implicite. Si une
    conversion plus complexe est nécessaire, une clause
    USING peut être ajoutée qui indique comment calculer
    les nouvelles valeurs à partir des anciennes.
   
PostgreSQL tente de convertir la valeur par défaut de la colonne le cas échéant, ainsi que toute contrainte impliquant la colonne. Mais ces conversions peuvent échouer ou produire des résultats surprenants. Il est souvent préférable de supprimer les contraintes de la colonne avant d'en modifier le type, puis d'ajouter ensuite les contraintes convenablement modifiées.