Intégration de bases de données (SQLx/Diesel)
Intégrez votre service web Rust à des bases de données à l’aide d’ORM ou de constructeurs de requêtes populaires comme SQLx ou Diesel.
Intégration de bases de données (SQLx/Diesel) est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 2 sur 3. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 3 leçons au total.
Pourquoi utiliser des bases de données pour le web ?
Les services web doivent souvent stocker et récupérer des données de manière persistante. Pensez aux profils utilisateurs, aux catalogues de produits ou aux articles de blog : ces données doivent exister quelque part au-delà de la mémoire de votre programme.
Les bases de données offrent une manière structurée de gérer ces données, en garantissant qu’elles sont sûres, cohérentes et accessibles. Intégrer votre service web Rust à une base de données est une tâche essentielle pour la plupart des applications réelles.
SQLx : votre allié pour les bases de données asynchrones
En Rust, vous disposez d’excellents outils pour interagir avec les bases de données. Deux choix populaires sont SQLx et Diesel.
- SQLx : une caisse SQL asynchrone entièrement écrite en Rust, dont les requêtes sont vérifiées lors de la compilation. Elle est souvent privilégiée pour les services web asynchrones construits avec des frameworks comme Tokio.
- Diesel : un puissant ORM (outil de mapping objet-relationnel) qui offre une approche plus abstraite pour interagir avec votre base de données, en associant directement les structures Rust aux tables de la base de données. Il fonctionne généralement de manière synchrone.
Dans cette leçon, nous nous concentrerons sur SQLx en raison de son excellent support de l’asynchronisme, particulièrement adapté au développement moderne de services web Rust.
Configurer SQLx : dépendances
Avant d’écrire du code, vous devez ajouter sqlx et tokio au fichier Cargo.toml de votre projet. tokio fournit l’environnement d’exécution asynchrone dont sqlx a besoin.
Par exemple, pour utiliser SQLite (une base de données simple, stockée dans un fichier, adaptée au développement local) avec SQLx, votre fichier Cargo.toml pourrait ressembler à ceci :
[dependencies]
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "sqlite"] }
tokio = { version = "1", features = ["full"] }Vous utiliserez également généralement une variable d’environnement DATABASE_URL pour configurer la chaîne de connexion à votre base de données.
Se connecter à votre première base de données
Établissons une connexion à une base de données SQLite en mémoire. SQLx utilise des pools de connexions, qui gèrent efficacement plusieurs connexions à la base de données afin de traiter les requêtes simultanées de votre service web.
Essayez d’exécuter cet exemple :
use sqlx::SqlitePool;
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
// Use an in-memory SQLite database for simplicity
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
println!("Successfully connected to the database!");
// In a real web app, 'pool' would be passed around or stored in app state.
Ok(())
}Structurer les données avec des tables
Avant de pouvoir stocker des données, nous devons définir le schéma de notre base de données à l’aide du DDL (langage de définition des données). Créons une table tasks simple.
La macro sqlx::query! vous permet d’intégrer directement du SQL dans votre code Rust. Elle effectue même des vérifications de vos requêtes SQL lors de la compilation !
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
// Create a 'tasks' table if it doesn't exist
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
println!("Table 'tasks' created successfully!");
Ok(())
}Ajouter de nouveaux enregistrements
Maintenant que nous avons une table, ajoutons quelques données ! Nous utiliserons l’instruction INSERT avec la liaison de paramètres. Cela protège contre les injections SQL et rend vos requêtes plus sûres.
Remarquez que les espaces réservés ? sont utilisés pour les paramètres, et que les valeurs sont transmises à .bind().
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
// Insert a new task
let description = "Learn SQLx";
let completed = false;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
description,
completed
).execute(&pool).await?;
println!("Task '{}' inserted successfully!", description);
Ok(())
}Récupérer des données avec SELECT
Pour récupérer des données de notre table tasks, nous utilisons l’instruction SELECT. SQLx fournit des méthodes comme .fetch_all() ou .fetch_one() pour obtenir les résultats.
Vous pouvez parcourir les lignes renvoyées et accéder aux colonnes par leur nom ou leur index.
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Learn SQLx", false
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Build a web app", false
).execute(&pool).await?;
// Fetch and print all tasks
println!("\n--- All Tasks ---");
let rows = query!("SELECT id, description, completed FROM tasks")
.fetch_all(&pool).await?;
for row in rows {
println!("ID: {}, Desc: {}, Done: {}",
row.id, row.description, row.completed);
}
Ok(())
}Des données sûres grâce aux types et aux structures
Extraire manuellement les données des lignes peut être source d’erreurs. La macro query_as! de SQLx, combinée à #[derive(FromRow)], vous permet d’associer directement les résultats d’une requête à des structures Rust !
Cette approche offre une forte sécurité de typage et rend votre code beaucoup plus clair et facile à manipuler.
use sqlx::{FromRow, SqlitePool, query, query_as};
use tokio;
#[derive(Debug, FromRow)]
struct Task {
id: i64,
description: String,
completed: bool,
}
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Learn SQLx", false
).execute(&pool).await?;
// Fetch tasks directly into our Task struct
println!("\n--- Tasks as Structs ---");
let tasks = query_as::<_, Task>("SELECT id, description, completed FROM tasks")
.fetch_all(&pool).await?;
for task in tasks {
println!("{:?}", task);
}
Ok(())
}Modifier et supprimer des enregistrements
La mise à jour et la suppression de données suivent un modèle similaire à celui de l’insertion. Vous utilisez les instructions SQL UPDATE et DELETE avec la liaison de paramètres.
- UPDATE : modifie les lignes existantes en fonction d’une clause
WHERE. - DELETE : supprime les lignes en fonction d’une clause
WHERE.
Soyez toujours vigilant avec les clauses WHERE dans UPDATE et DELETE afin d’éviter toute perte de données involontaire !
use sqlx::{SqlitePool, query};
use tokio;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let database_url = "sqlite::memory:";
let pool = SqlitePool::connect(&database_url).await?;
query!(
"CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
description TEXT NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE
)"
).execute(&pool).await?;
query!(
"INSERT INTO tasks (description, completed) VALUES (?, ?)",
"Finish lesson", false
).execute(&pool).await?;
let task_id_to_update = 1;
// Update a task
query!(
"UPDATE tasks SET completed = ? WHERE id = ?",
true,
task_id_to_update
).execute(&pool).await?;
println!("Task {} updated.", task_id_to_update);
// Delete a task (uncomment to run, careful with IDs after update)
// let task_id_to_delete = 1;
// query!(
// "DELETE FROM tasks WHERE id = ?",
// task_id_to_delete
// ).execute(&pool).await?;
// println!("Task {} deleted.", task_id_to_delete);
Ok(())
}Testez vos compétences en bases de données
Lesquelles des affirmations suivantes sont TRUE concernant SQLx dans les services web Rust ?
Intégration d’une base de données : points essentiels
Vous avez franchi une étape importante dans la création de services web Rust robustes en apprenant à intégrer une base de données !
- Persistance : les bases de données sont essentielles pour stocker les données d’une application.
- SQLx : une caisse SQL asynchrone, vérifiée lors de la compilation, particulièrement adaptée aux services web.
- Pools de connexions : indispensables pour accéder efficacement et simultanément à une base de données.
- CRUD : nous avons vu comment créer (
INSERT), récupérer (SELECT), mettre à jour (UPDATE) et supprimer (DELETE) des données. - Sécurité des types :
query_as!et#[derive(FromRow)]permettent d’associer les données de manière sûre et ergonomique.
Vous pouvez maintenant explorer l’intégration de ces opérations de base de données dans de véritables routes web !
Questions Fréquemment Posées
La leçon « Intégration de bases de données (SQLx/Diesel) » est-elle gratuite ?
Oui — le texte complet de « Intégration de bases de données (SQLx/Diesel) » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 3 leçons au total.
Qu'est-ce que j'apprendrai dans « Intégration de bases de données (SQLx/Diesel) » ?
Intégrez votre service web Rust à des bases de données à l’aide d’ORM ou de constructeurs de requêtes populaires comme SQLx ou Diesel. Tu pratiques Learn Rust Coding avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Learn Rust Coding ?
Aucune expérience préalable n'est requise. Learn Rust Coding sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 3.
Combien de temps prend la leçon « Intégration de bases de données (SQLx/Diesel) » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Learn Rust Coding ?
Oui. Chaque leçon Learn Rust Coding inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- API REST avec Actix-web/Rocket
- Intégration de bases de données (SQLx/Diesel)
- Authentification et autorisation