Pourquoi JavaScript et PostgreSQL font-ils bon ménage ?
\n\nSi vous codez en JavaScript (surtout sur Node.js) et que vous utilisez encore MySQL ou, que Dieu vous garde, SQLite en production, — vous perdez de l'argent et vos nerfs. PostgreSQL n'est pas "juste une base de données de plus". C'est un couteau suisse pour les données, capable de tout faire : des JOIN complexes aux documents JSON, en passant par la recherche plein texte et les requêtes géospatiales. Et la combinaison JavaScript + PostgreSQL est le standard moderne pour les applications web, les microservices et l'analytique.
\n\nDans ce guide, nous allons couvrir tout ce qu'un développeur Node.js doit savoir : de l'installation du pilote aux transactions, migrations et optimisations. Pas de blabla — que du code et de la pratique.
\n\nÉtape 1 : Installation et configuration du pilote pg
\n\nPour travailler avec PostgreSQL depuis JavaScript, on utilise le package pg — le client officiel. Il s'installe en une seconde :
npm install pg\n\nCréons maintenant une connexion. Deux approches existent : Client (une seule connexion) et Pool (pool de connexions). Pour la production, utilisez toujours Pool — il gère la réutilisation des connexions et ne fait pas planter la base en cas de charge.
\n\nconst { Pool } = require('pg');\n\nconst pool = new Pool({\n user: 'your_user',\n host: 'localhost',\n database: 'your_db',\n password: 'your_password',\n port: 5432,\n max: 20, // max. connexions dans le pool\n idleTimeoutMillis: 30000,\n connectionTimeoutMillis: 2000,\n});\n\n// Test de connexion\npool.query('SELECT NOW()')\n .then(res => console.log('✅ Connecté :', res.rows[0].now))\n .catch(err => console.error('❌ Erreur :', err));\n\nImportant : Ne codez jamais les mots de passe en dur. Utilisez des variables d'environnement (process.env.DATABASE_URL) ou un gestionnaire de secrets.
Étape 2 : CRUD — les bases
\n\nToute application commence par le CRUD (Create, Read, Update, Delete). Analysons chaque opération avec JavaScript et PostgreSQL.
\n\nCréation de table (DDL)
\n\nconst createTable = async () => {\n const query = `\n CREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n name VARCHAR(100) NOT NULL,\n email VARCHAR(255) UNIQUE NOT NULL,\n age INTEGER CHECK (age > 0),\n created_at TIMESTAMP DEFAULT NOW()\n );\n `;\n await pool.query(query);\n console.log('✅ Table users créée');\n};\n\ncreateTable();\n\nINSERT — ajout de données
\n\nconst addUser = async (name, email, age) => {\n // Utilisation d'une requête paramétrée — protection contre les injections SQL !\n const query = `\n INSERT INTO users (name, email, age)\n VALUES ($1, $2, $3)\n RETURNING *;\n `;\n const values = [name, email, age];\n const res = await pool.query(query, values);\n console.log('✅ Utilisateur ajouté :', res.rows[0]);\n return res.rows[0];\n};\n\n// Exemple d'appel\naddUser('Anna Petrova', 'anna@example.com', 28);\n\nSELECT — lecture avec filtrage
\n\nconst getUsers = async (minAge = 0) => {\n const query = 'SELECT * FROM users WHERE age > $1 ORDER BY created_at DESC';\n const res = await pool.query(query, [minAge]);\n console.log(`📊 Utilisateurs trouvés : ${res.rowCount}`);\n return res.rows;\n};\n\ngetUsers(25).then(users => console.log(users));\n\nUPDATE — mise à jour d'un enregistrement
\n\nconst updateUserEmail = async (id, newEmail) => {\n const query = `\n UPDATE users\n SET email = $2, updated_at = NOW()\n WHERE id = $1\n RETURNING *;\n `;\n const res = await pool.query(query, [id, newEmail]);\n if (res.rowCount === 0) {\n console.log('⚠️ Utilisateur non trouvé');\n return null;\n }\n console.log('✅ Email mis à jour :', res.rows[0]);\n return res.rows[0];\n};\n\nDELETE — suppression
\n\nconst deleteUser = async (id) => {\n const query = 'DELETE FROM users WHERE id = $1 RETURNING *';\n