Blog de Norore
Geek en perdition dans un monde qui va trop vite

Code en vrac : mettre à jour une colonne d’une table dans PostgreSQL en Bash

10 Jul 2022 - Norore
Un vieil ensemble de casiers à fiche en bois ancien ciré. Les poignées sont en métal vieilli et les étiquettes portant les numéros de casier, sous les poignées, sont en partie effacées. Au-dessus des poignées se trouve d’autres étiquettes avec les noms des dossiers.

Vous est-il déjà arrivé, dans le cadre de votre travail, de devoir mettre à jour une colonne spécifique dans votre base de données PostgreSQL ? C’est une tâche somme toute assez basique et rapide à faire. Mais quand ce n’est à faire qu’une fois par an, si vous avez déjà sauté sur cinq projets différents, comment vous faciliter la tâche pour ne pas avoir à retrouver la base de données, la table et la colonne ? Est-ce que faire un script Bash peut être une solution ? C’est une question que je me suis posé·e cette semaine et l’exercice a été assez amusant à faire. Voyons voir comment ça marche !

Faire une requête en ligne de commande

La première question qui vient à l’esprit, avant de faire un script, c’est comment faire une requête en ligne de commande.

Pour mettre à jour une table, il faut utiliser la syntaxe UPDATE table SET column. Rien de bien sorcier. On peut le faire très facilement depuis l’interface de PostgreSQL. Mais peut-on passer la commande directement à la ligne de commande psql ? Un petit tour rapide sur le manuel nous permet de trouver l’option -c. Testons.

psql -h localhost -U postgres -d database -c "SELECT COUNT(column) FROM table;"
Mot de passe pour l'utilisateur postgres :

Mince, ça marche presque. Sauf que devoir donner le mot de passe par la console n’est pas forcément le plus simple à faire. Si l’on s’attarde davantage sur le manuel de psql, on peut lire qu’il demande un fichier d’environnement PGPASSFILE, conventionnellement nommé .pgpass.

Sur une machine de développement, voici ce que vous pouvez mettre :

localhost:5432:*:postgres:postgres

Les paramètres, chacun étant séparé par le caractère deux-points, qui sont attendus sont les suivants :

  1. l’hôte
  2. le port
  3. le nom de la base de données, dans notre exemple, database, sinon * est à utiliser en joker
  4. le nom de l’utilisateur
  5. le mot de passe de l’utilisateur

N’oubliez pas d’importer le fichier dans l’environnement Bash, n’hésitez pas non plus à l’ajouter dans votre profil :

export PGPASSFILE=".pgpass"

Retestons notre précédente commande :

psql -h localhost -U postgres -d pg_scolarite -c "SELECT COUNT(moodle) FROM maquettes;"
 count 
-------
   255
(1 ligne)

Impeccable, ça marche ! Voyons voir comment nous pourrions faire la même chose à l’aide d’un script.

Un petit script Bash qui fait le boulot

Nous venons donc de voir comment faire une requête SQL depuis la ligne de commande. C’est bien, maintenant nous allons pouvoir faire un script Bash vite fait, pas forcément bien fait, qui fait le boulot à notre place.

On a besoin de connaître les paramètres de connexion à la base de données PostgreSQL, de créer et écrire un fichier .pgpass qui sera utilisé par psql, de lancer la commande, et de nettoyer derrière nous :

#!/bin/bash

dbhost="localhost"
dbport="5432"
dbname="database"
dbuser="user"
dbpass="password"

pgpass=".pgpass"

if [ ! -f $pgpass ]
then
  touch "$pgpass" && chmod 600 "$pgpass"
  echo "$dbhost:$dbport:$dbname:$dbuser:$dbpass" > "$pgpass"
fi

export PGPASSFILE="$pgpass"

psql -U $dbuser -d "$dbname" -h "$dbhost" -p "$dbport" -c "UPDATE table SET column=FALSE;"

rm "$pgpass"

Et voilà ! La prochaine fois que vous devrez mettre à jour cette colonne, il vous suffira d’exécuter ce script !

Un gros avantage de ce script également, c’est que vous pouvez programmer une tâche CRON qui exécutera ce script à votre place.

Des améliorations possibles

Comme dit, c’est un script vite fait, mais pas forcément bien fait.

Dans les améliorations possibles que je vois, on peut récupérer dans les paramètres de la ligne de commande les paramètres de connexion à la base de données. On peut également donner un autre nom pour le PGPASSFILE, afin d’éviter de potentiellement écraser un fichier déjà existant. Ces paramètres seront à préciser dans votre tâche CRON si vous en programmez une.


Source de l’image d’accroche :

Un vieil ensemble de casiers à fiche en bois ancien ciré. Les poignées sont en métal vieilli et les étiquettes portant les numéros de casier, sous les poignées, sont en partie effacées. Au-dessus des poignées se trouve d’autres étiquettes avec les noms des dossiers. Image par Jan Antonin Kolar, sur le site Unsplash, sous license Unsplash