⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Pré-ensemencement de la base de données avec le schéma et les données au démarrage pour l'environnement de développement

Le pré-ensemencement des bases de données avec des données et un schéma essentiels pendant le développement local est une pratique courante pour améliorer le flux de travail de développement et de test. En simulant des scénarios réels, cette pratique aide à détecter rapidement les problèmes de frontend, assure l'alignement entre les administrateurs de bases de données et les ingénieurs logiciels, et facilite une collaboration plus fluide. Le pré-ensemencement offre des avantages tels que des déploiements confiants, une cohérence entre les environnements et une détection précoce des problèmes, améliorant ainsi globalement le processus de développement.

Dans ce guide, vous apprendrez à :

  • Utiliser Docker pour lancer un conteneur Postgres
  • Pré-ensemencer Postgres en utilisant un script SQL
  • Pré-ensemencer Postgres en copiant des fichiers SQL dans l'image Docker
  • Pré-ensemencer Postgres en utilisant du code JavaScript

Utilisation de Postgres avec Docker

L'image Docker officielle pour Postgres fournit un moyen pratique d'exécuter une base de données Postgres sur votre machine de développement. Une image Docker Postgres est un environnement pré-configuré qui encapsule le système de base de données PostgreSQL. C'est une unité autonome, prête à fonctionner dans un conteneur Docker. En utilisant cette image, vous pouvez rapidement et facilement mettre en place une instance Postgres sans avoir besoin de configuration manuelle.

Prérequis

Les prérequis suivants sont nécessaires pour suivre ce guide pratique :

Lancement de Postgres

Lancez une démonstration rapide de Postgres en suivant les étapes suivantes :

  1. Ouvrez le terminal et exécutez la commande suivante pour démarrer un conteneur Postgres.

    Cet exemple lancera un conteneur Postgres, exposera le port 5432 sur l'hôte pour permettre à une application s'exécutant nativement de s'y connecter avec le mot de passe mysecretpassword.

    $ docker run -d --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=mysecretpassword postgres
    
  2. Vérifiez que Postgres est opérationnel en sélectionnant le conteneur et en vérifiant les journaux sur le tableau de bord Docker.

    La base de données PostgreSQL semble contenir une base de données ; initialisation ignorée
    
    2024-09-08 09:09:47.136 UTC [1] LOG:  démarrage de PostgreSQL 16.4 (Debian 16.4-1.pgdg120+1) sur aarch64-unknown-linux-gnu, compilé par gcc (Debian 12.2.0-14) 12.2.0, 64-bit
    2024-09-08 09:09:47.137 UTC [1] LOG:  écoute sur l'adresse IPv4 "0.0.0.0", port 5432
    2024-09-08 09:09:47.137 UTC [1] LOG:  écoute sur l'adresse IPv6 "::", port 5432
    2024-09-08 09:09:47.139 UTC [1] LOG:  écoute sur le socket Unix "/var/run/postgresql/.s.PGSQL.5432"
    2024-09-08 09:09:47.142 UTC [29] LOG:  le système de base de données a été arrêté à 2024-09-08 09:07:09 UTC
    2024-09-08 09:09:47.148 UTC [1] LOG:  le système de base de données est prêt à accepter les connexions
  3. Connectez-vous à Postgres depuis le système local.

    Le psql est le shell interactif de PostgreSQL qui est utilisé pour se connecter à une base de données Postgres et vous permettre de commencer à exécuter des commandes SQL. En supposant que vous avez déjà l'utilitaire psql installé sur votre système local, il est temps de se connecter à la base de données Postgres. Exécutez la commande suivante sur votre terminal local :

    $ docker exec -it postgres psql -h localhost -U postgres
    

    Vous pouvez maintenant exécuter toutes les requêtes ou commandes SQL dont vous avez besoin dans l'invite psql.

    Utilisez \q ou \quit pour quitter le shell interactif de Postgres.

Pré-ensemencer la base de données Postgres en utilisant un script SQL

Maintenant que vous vous êtes familiarisé avec Postgres, il est temps de voir comment le pré-ensemencer avec des données d'exemple. Dans cette démonstration, vous allez d'abord créer un script qui contient des commandes SQL. Le script définit la base de données, la structure de la table et insère des données d'exemple. Ensuite, vous vous connecterez à la base de données pour vérifier les données.

En supposant que vous avez une instance de base de données Postgres existante en cours d'exécution, suivez ces étapes pour ensemencer la base de données.

  1. Créez un fichier vide nommé seed.sql et ajoutez le contenu suivant.

    CREATE DATABASE sampledb;
    
    \c sampledb
    
    CREATE TABLE users (
      id SERIAL PRIMARY KEY,
      name VARCHAR(50),
      email VARCHAR(100) UNIQUE
    );
    
    INSERT INTO users (name, email) VALUES
      ('Alpha', '[email protected]'),
      ('Beta', '[email protected]'),
      ('Gamma', '[email protected]');

    Le script SQL crée une nouvelle base de données appelée sampledb, s'y connecte et crée une table users. La table comprend un id auto-incrémenté comme clé primaire, un champ name d'une longueur maximale de 50 caractères et un champ email unique pouvant contenir jusqu'à 100 caractères.

    Après avoir créé la table, la commande INSERT insère trois utilisateurs dans la table users avec leurs noms et e-mails respectifs. Cette configuration forme une structure de base de données de base pour stocker les informations des utilisateurs avec des adresses e-mail uniques.

  2. Ensemencez la base de données.

    Il est temps d'alimenter le contenu du seed.sql directement dans la base de données en utilisant l'opérateur <. La commande est utilisée pour exécuter un script SQL nommé seed.sql contre une base de données Postgres nommée sampledb.

    $ cat seed.sql | docker exec -i postgres psql -h localhost -U postgres -f-
    

    Une fois la requête exécutée, vous verrez les résultats suivants :

    CREATE DATABASE
    Vous êtes maintenant connecté à la base de données "sampledb" en tant qu'utilisateur "postgres".
    CREATE TABLE
    INSERT 0 3
  3. Exécutez la commande psql suivante pour vérifier si la table nommée users est peuplée dans la base de données sampledb ou non.

    $ docker exec -it postgres psql -h localhost -U postgres sampledb
    

    Vous pouvez maintenant exécuter \l dans le shell psql pour lister toutes les bases de données sur le serveur Postgres.

    sampledb=# \l
                                                 Liste des bases de données
     Nom      | Propriétaire | Encodage | Collation  | Type C     | ICU Locale | Fournisseur de locale | Privilèges d'accès
    -----------+----------+----------+------------+------------+------------+-----------------+-----------------------
    postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            |
    sampledb  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            |
    template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/postgres          +
              |          |          |            |            |            |                 | postgres=CTc/postgres
    template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/postgres          +
              |          |          |            |            |            |                 | postgres=CTc/postgres
    (4 lignes)
    

    Pour récupérer toutes les données de la table users, entrez la requête suivante :

    sampledb=# SELECT * FROM users;
     id | nom   |       email
    ----+-------+-------------------
      1 | Alpha | [email protected]
      2 | Beta  | [email protected]
      3 | Gamma | [email protected]
    (3 lignes)
    

    Utilisez \q ou \quit pour quitter le shell interactif de Postgres.

Pré-ensemencer la base de données en montant un script SQL par liaison

Dans Docker, le montage fait référence à la mise à disposition de fichiers ou de répertoires du système hôte à l'intérieur d'un conteneur. Cela vous permet de partager des données ou des fichiers de configuration entre l'hôte et le conteneur, offrant une plus grande flexibilité et persistance.

Maintenant que vous avez appris à lancer Postgres et à pré-ensemencer la base de données à l'aide d'un script SQL, il est temps d'apprendre à monter un fichier SQL directement dans le répertoire d'initialisation des conteneurs Postgres (/docker-entrypoint-initdb.d). Le /docker-entrypoint-initdb.d est un répertoire spécial dans les conteneurs Docker PostgreSQL qui est utilisé pour initialiser la base de données lorsque le conteneur est démarré pour la première fois.

Assurez-vous d'arrêter tous les conteneurs Postgres en cours d'exécution (avec les volumes) pour éviter les conflits de ports avant de suivre les étapes :

$ docker container stop postgres
  1. Modifiez le seed.sql avec les entrées suivantes :

    CREATE TABLE IF NOT EXISTS users (
     id SERIAL PRIMARY KEY,
     name VARCHAR(50),
     email VARCHAR(100) UNIQUE
    );
    
    INSERT INTO users (name, email) VALUES
     ('Alpha', '[email protected]'),
     ('Beta', '[email protected]'),
     ('Gamma', '[email protected]')
    ON CONFLICT (email) DO NOTHING;
  2. Créez un fichier texte nommé Dockerfile et copiez le contenu suivant.

    # syntax=docker/dockerfile:1
    FROM postgres:latest
    COPY seed.sql /docker-entrypoint-initdb.d/

    Ce Dockerfile copie le script seed.sql directement dans le répertoire d'initialisation du conteneur PostgreSQL.

  3. Utilisez Docker Compose.

    L'utilisation de Docker Compose facilite encore plus la gestion et le déploiement du conteneur PostgreSQL avec la base de données ensemencée. Ce fichier compose.yml définit un service Postgres nommé db utilisant la dernière image Postgres, qui configure une base de données avec le nom sampledb, ainsi qu'un utilisateur postgres et un mot de passe mysecretpassword.

    services:
      db:
        build:
          context: .
          dockerfile: Dockerfile
        container_name: my_postgres_db
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: mysecretpassword
          POSTGRES_DB: sampledb
        ports:
          - "5432:5432"
        volumes:
          - data_sql:/var/lib/postgresql/data   # Stockage de données persistant
    
    volumes:
      data_sql:

    Il mappe le port 5432 sur l'hôte au 5432 du conteneur, vous permettant d'accéder à la base de données Postgres depuis l'extérieur du conteneur. Il définit également data_sql pour la persistance des données de la base de données, garantissant que les données ne sont pas perdues lorsque le conteneur est arrêté.

    Il est important de noter que le mappage de port vers l'hôte n'est nécessaire que si vous souhaitez vous connecter à la base de données à partir de programmes non conteneurisés. Si vous conteneurisez le service qui se connecte à la base de données, vous devez vous connecter à la base de données sur un réseau de pont personnalisé.

  4. Lancez le service Compose.

    En supposant que vous avez placé le fichier seed.sql dans le même répertoire que le Dockerfile, exécutee la commande suivante :

    $ docker compose up -d --build
    
  5. Il est temps de vérifier si la table users est peuplée avec les données.

    $ docker exec -it my_postgres_db psql -h localhost -U postgres sampledb
    
    sampledb=# SELECT * FROM users;
      id | nom   |       email
    ----+-------+-------------------
       1 | Alpha | alpha@example.com
       2 | Beta  | beta@example.com
       3 | Gamma | gamma@example.com
     (3 lignes)
    
    sampledb=#

Pré-ensemencer la base de données en utilisant du code JavaScript

Maintenant que vous avez appris à ensemencer la base de données en utilisant diverses méthodes comme le script SQL, le montage de volumes, etc., il est temps d'essayer de le faire en utilisant du code JavaScript.

  1. Créez un fichier .env avec ce qui suit :

    POSTGRES_USER=postgres
    POSTGRES_DB_HOST=localhost
    POSTGRES_DB=sampledb
    POSTGRES_PASSWORD=mysecretpassword
    POSTGRES_PORT=5432
  2. Créez un nouveau fichier JavaScript appelé seed.js avec le contenu suivant :

    Le code JavaScript suivant importe le package dotenv qui est utilisé pour charger les variables d'environnement à partir d'un fichier .env. La méthode .config() lit le fichier .env et définit les variables d'environnement comme des propriétés de l'objet process.env. Cela vous permet de stocker des informations sensibles comme les identifiants de base de données en dehors de votre code.

    Ensuite, il crée une nouvelle instance Pool à partir de la bibliothèque pg, qui fournit un pool de connexion pour des interactions de base de données efficaces. La fonction seedData est définie pour effectuer les opérations d'ensemencement de la base de données.

    Elle est appelée à la fin du script pour initier le processus d'ensemencement. Le bloc try...catch...finally est utilisé pour la gestion des erreurs.

    require('dotenv').config();  // Load environment variables from .env file
    const { Pool } = require('pg');
    
    // Create a new pool using environment variables
    const pool = new Pool({
      user: process.env.POSTGRES_USER,
      host: process.env.POSTGRES_DB_HOST,
      database: process.env.POSTGRES_DB,
      port: process.env.POSTGRES_PORT,
      password: process.env.POSTGRES_PASSWORD,
    });
    
    const seedData = async () => {
      try {
         // Drop the table if it already exists (optional)
         await pool.query(`DROP TABLE IF EXISTS todos;`);
    
         // Create the table with the correct structure
         await pool.query(`
           CREATE TABLE todos (
             id SERIAL PRIMARY KEY,
             task VARCHAR(255) NOT NULL,
             completed BOOLEAN DEFAULT false
               );
         `   );
    
         // Insert seed data
         await pool.query(`
           INSERT INTO todos (task, completed) VALUES
           ('Watch netflix', false),
           ('Finish podcast', false),
           ('Pick up kid', false);
           `);
           console.log('Database seeded successfully!');
         } catch (err) {
           console.error('Error seeding the database', err);
         } finally {
           pool.end();
        }
      };
    
      // Call the seedData function to run the script
      seedData();
  3. Lancez le processus d'ensemencement

    $ node seed.js
    

    Vous devriez voir la commande suivante :

    Database seeded successfully!
  4. Vérifiez si la base de données est ensemencée correctement :

    $ docker exec -it postgres psql -h localhost -U postgres sampledb
    
    sampledb=# SELECT * FROM todos;
    id |      task      | completed
    ----+----------------+-----------
    1 | Watch netflix  | f
    2 | Finish podcast | f
    3 | Pick up kid    | f
    (3 rows)  
    

Récapitulatif

Le pré-ensemencement d'une base de données avec un schéma et des données au démarrage est essentiel pour créer un environnement de test cohérent et réaliste, ce qui aide à identifier les problèmes précocement dans le développement et à aligner le travail frontend et backend. Ce guide vous a fourni les connaissances et les étapes pratiques pour réaliser le pré-ensemencement en utilisant diverses méthodes, y compris le script SQL, l'intégration Docker et le code JavaScript.