📅 SAISON B Semaine 5 Épisode 3 - Introduction aux ORM
📚 Notions du jour
Aujourd’hui, nous avons exploré un concept clé pour les applications modernes : les ORM (Object-Relational Mapping). Jusqu’à présent, nous utilisions un datamapper "manuel" pour interagir avec notre base de données. Cependant, cette approche présente des limites :
- Code répétitif : Écrire manuellement chaque requête SQL devient fastidieux.
- Risque d’erreurs : Les requêtes SQL mal écrites peuvent causer des bugs ou des failles de sécurité.
- Couplage fort : Le code est fortement lié à la structure de la base de données.
- Maintenance difficile : Les changements dans la base de données nécessitent des modifications dans tout le code.
Voici les notions aborbées durant cette journée :
- Les limites d’un Data Mapper manuel dans un projet complexe.
- Le concept d’ORM (Object-Relational Mapping) : un traducteur Objet <=> SQL.
- Présentation de Sequelize comme solution ORM pour Node.js.
- L’installation des paquets
sequelizeetpg. - La création et la configuration d’une instance de Sequelize.
- Le test de la connexion à la base de données avec
sequelize.authenticate().
Aujourd’hui, nous avons exploré un concept clé pour les applications modernes : les ORM (Object-Relational Mapping). Jusqu’à présent, nous utilisions un datamapper manuel pour interagir avec notre base de données. Cependant, cette approche présente des limites :
- Code répétitif : Écrire manuellement chaque requête SQL devient fastidieux.
- Risque d’erreurs : Les requêtes SQL mal écrites peuvent causer des bugs ou des failles de sécurité.
- Couplage fort : Le code est fortement lié à la structure de la base de données.
- Maintenance difficile : Les changements dans la base de données nécessitent des modifications dans tout le code.
🔧 Qu’est-ce qu’un ORM ?
Un ORM (Object-Relational Mapping) est une bibliothèque qui permet de :
- Mapper les tables d’une base de données relationnelle (PostgreSQL, MySQL, etc.) à des objets JavaScript.
- Automatiser la génération des requêtes SQL (CRUD : Create, Read, Update, Delete).
- Abstraire les détails de la base de données, ce qui rend le code plus portable.
Un ORM comme Sequelize agit comme un traducteur entre le monde objet (JavaScript) et le monde relationnel (SQL). Il permet de :
✅ Manipuler les données comme des objets (plus besoin d’écrire du SQL manuellement).
✅ Générer automatiquement les requêtes SQL.
✅ Gérer les relations entre tables (1:1, 1:N, N:N) de manière intuitive.
✅ Sécuriser les requêtes (protection contre les injections SQL).
Exemple : Avec un ORM, au lieu d’écrire :
On écrit :
💠 Présentation de Sequelize
Sequelize est un ORM populaire pour Node.js qui supporte :
- PostgreSQL, MySQL, SQLite, MSSQL, et MariaDB.
- Les migrations pour gérer les changements de schéma.
- Les relations entre modèles (1:1, 1:N, N:N).
- Les transactions pour garantir l’intégrité des données.
📦 Installation et Configuration de Sequelize
1️⃣ Installer Sequelize et le Driver PostgreSQL
sequelize: Le cœur de l’ORM.pg: Le driver pour se connecter à PostgreSQL.pg-hstore: Pour gérer le type de donnéeshstorede PostgreSQL (optionnel).
2️⃣ Configurer une Instance de Sequelize
Créer un fichier src/database/sequelize.js pour configurer la connexion à la base de données.
import { Sequelize } from "sequelize";
// Crée l'instance de Sequelize
const sequelize = new Sequelize(process.env.DATABASE_URL, {
// Define default parameters for Models with option `define: {...}`
define: {
// Option to keep the given table name as is
freezeTableName: true,
// Option to automatically manage createdAt/updatedAt columns
timestamps: true,
// Option that allows automatic generation of fields in snake_case (for exp: createdAt => created_at)
underscored: true
}
});
export default sequelize;
Explications :
Sequelize: Classe principale pour créer une instance de connexion.process.env.DATABASE_URL: variable d'environnement contenant les paramètres de connexion à la BDD.- option
define: permet de définir les paramètres par défaut que possèderont les Models de notre application.
3️⃣ Fichier .env pour les Variables d’Environnement
4️⃣ Tester la Connexion à la Base de Données
Avant de commencer à utiliser Sequelize, il est crucial de vérifier que la connexion à la base de données fonctionne.
// ... (previous code)
try {
await sequelize.authenticate();
console.log('Connection to the database OK');
} catch(error) {
console.error('Connection to the database NOT OK', error);
}
// To test connexion to DB run: node --env-file=.env database/sequelize-client.js
Explications :
sequelize.authenticate(): Méthode pour tester la connexion.- Si la connexion réussit, un message de succès s’affiche. Sinon, une erreur est loguée.
📝 Créer un Modèle avec Sequelize
Un modèle (Model) dans Sequelize représente une table dans la base de données. Chaque modèle est une classe qui étend Model de Sequelize.
Définir un Modèle Coffee
// src/models/Coffee.js
import { DataTypes } from 'sequelize';
import sequelize from '../database/sequelize.js';
const Coffee = sequelize.define(
'Coffee', // Model name
{
// Model attributes
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true;
},
description: {
type: DataTypes.TEXT,
},
reference: {
type: DataTypes.CHAR(9),
allowNull: false,
unique: true,
},
price_per_kg: {
type: DataTypes.DECIMAL,
allowNull: false,
},
available: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
},
{
// Model options
tableName: 'coffees', // Explicit table name
}
);
export default Coffee;
Explications :
sequelize.define(): Définit un nouveau modèle.- Premier argument : Nom du modèle (
Coffee). - Deuxième argument : Objet décrivant les colonnes de la table.
- Troisième argument : Options du modèle (ex:
tableName,timestamps).
- Premier argument : Nom du modèle (
DataTypes: Définit le type de chaque colonne (ex:STRING,INTEGER,DECIMAL).
💡 Ce Que J’ai Appris Aujourd’hui
- Un ORM comme Sequelize simplifie l’interaction avec une base de données en traduisant les objets JavaScript en requêtes SQL.
- La configuration de Sequelize est simple et permet de se connecter à différentes bases de données (PostgreSQL, MySQL, etc.).
- Les modèles Sequelize représentent des tables et permettent de définir des colonnes, des types de données, et des relations.
⌨️ Challenge du jour : "Projet oCoffee" – projet fil rouge (suite)
☕️ Présentation du Challenge
Aujourd’hui, l’objectif était d’intégrer Sequelize dans notre projet oCoffee pour remplacer notre datamapper manuel. Sequelize est un ORM (Object-Relational Mapping) qui permet de communiquer avec la base de données en JavaScript, sans écrire de SQL manuellement.
Pourquoi ?
- Simplifier l’accès aux données : Plus besoin d’écrire des requêtes SQL à la main.
- Gagner en sécurité : Sequelize protège contre les injections SQL et gère les connexions à la base de données.
- Factoriser le code : Les modèles Sequelize permettent de représenter les tables de manière élégante et réutilisable.
Étapes à réaliser :
Reprendre les étapes vues en cours pour intégrer Sequelize à notre projet d'entraînement oCoffee.
- Installer les paquets nécessaires (
sequelizeetpg). - Configurer une instance de Sequelize dans un fichier dédié (
sequelize-client.js). - Tester la connexion à la base de données.
- Définition du Model
Countrysur la base de ce que nous avons fait pour le ModelCoffee.
📌 Étapes à Réaliser
Il ne sera pas nécessaire ici de présenter à nouveau les étapes réalisées pour l'intégration de Sequelize que j'ai déjà présentées ici 👉 intégration Sequelize
Définition du Model Country
Objectif : Définir un modèle Country avec Sequelize, en utilisant la syntaxe sequelize.define().
Ma proposition :
import { DataTypes } from 'sequelize';
import sequelize from '../../database/sequelize-client.js';
const Country = sequelize.define(
'country',
{
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true;
},
},
{
tableName: 'countries',
}
);
export default Country;
💡 Ce Que J’ai Appris avec ce Challenge
- Sequelize simplifie la connexion à une base de données en gérant les détails techniques.
- La configuration de Sequelize est flexible et permet d’adapter son comportement (ex:
freezeTableName,underscored). - Tester la connexion avec
sequelize.authenticate()est une étape cruciale pour s’assurer que tout fonctionne avant de continuer. - Définir des modèles avec
sequelize.define()permet de représenter les tables de manière claire.