Un guide pour travailler avec des bases de données SQLite en Python
Démarrez avec les bases de données SQLite en Python à l'aide du module sqlite3 intégré.
SQLite est un système de gestion de bases de données relationnelles (SGBDR) léger et sans serveur, largement utilisé en raison de sa simplicité et de sa facilité d'intégration dans les applications.
Ainsi, que vous créiez une petite application, gériez des données localement ou prototypiez un projet, SQLite fournit une solution pratique pour stocker et interroger des données structurées. Dans ce didacticiel, vous apprendrez à travailler avec des bases de données SQLite à partir de Python à l'aide du module sqlite3 intégré.
En particulier, vous apprendrez à vous connecter à une base de données SQLite à partir de Python et à effectuer des opérations CRUD de base. Commençons.
Configuration de l'environnement
Dans un premier temps, créez un environnement virtuel dédié à votre projet (dans le répertoire du projet) et activez-le. Vous pouvez le faire en utilisant le module venv intégré comme ceci :
$ python3 -m venv v1
$ source v1/bin/activate
Dans ce didacticiel, nous utiliserons Faker pour générer des enregistrements synthétiques. Alors installez-le en utilisant pip :
$ pip3 install Faker
Le module sqlite3 est intégré à la bibliothèque standard Python, vous n'avez donc pas besoin de l'installer. Donc si vous avez installé Faker et que vous utilisez une version récente de Python, vous êtes prêt à partir !
Connexion à une base de données SQLite
Dans le répertoire du projet, créez un script Python et lancez-vous. Dans un premier temps pour interagir avec la base de données, nous devons établir une connexion avec la base de données.
Pour vous connecter à un exemple de base de données example.db, vous pouvez utiliser la fonction connect()
du module sqlite3 comme ceci :
conn = sqlite3.connect(‘example.db’)
Si la base de données existe déjà, alors il s'y connecte. Sinon, il crée la base de données dans le répertoire de travail.
Après nous être connectés à la base de données, nous créerons un curseur de base de données qui nous aidera à exécuter des requêtes. L'objet curseur dispose de méthodes pour exécuter des requêtes et récupérer les résultats de la requête. Cela fonctionne de manière très similaire à un gestionnaire de fichiers.
Il est souvent utile d'utiliser la connexion comme gestionnaire de contexte dans une instruction with comme ceci :
import sqlite3
# Connect to the db
with sqlite3.connect('example.db') as conn:
# create db cursor
# run queries
# commit changes
De cette façon, vous n’avez pas à vous soucier de fermer l’objet de connexion. La connexion est automatiquement fermée lorsque l'exécution quitte le bloc with. Cependant, nous fermerons explicitement les objets curseur dans ce didacticiel.
Création de tables de base de données
Créons maintenant une table clients
avec les champs obligatoires dans la base de données. Pour ce faire, nous créons d’abord un objet curseur. Nous exécutons ensuite une instruction CREATE TABLE et transmettons la chaîne de requête à la méthode execute()
appelée sur l'objet curseur :
import sqlite3
# Connect to the db
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Create customers table
cursor.execute('''
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
phone TEXT,
num_orders INTEGER
);
''')
conn.commit()
print("Customers table created successfully.")
cursor.close()
Lorsque vous exécutez le script, vous devriez voir le résultat suivant :
Output >>>
Customers table created successfully.
Effectuer des opérations CRUD
Effectuons quelques opérations CRUD de base sur la table de la base de données. Si vous le souhaitez, vous pouvez créer des scripts distincts pour chaque opération.
Insertion d'enregistrements
Nous allons maintenant insérer quelques enregistrements dans la table clients
. Nous utiliserons Faker pour générer des enregistrements synthétiques. Pour que les sorties restent lisibles, j'ai inséré seulement 10 enregistrements. Mais vous pouvez insérer autant d’enregistrements que vous le souhaitez.
import sqlite3
import random
from faker import Faker
# Initialize Faker object
fake = Faker()
Faker.seed(24)
# Connect to the db
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Insert customer records
num_records = 10
for _ in range(num_records):
first_name = fake.first_name()
last_name = fake.last_name()
email = fake.email()
phone = fake.phone_number()
num_orders = random.randint(0,100)
cursor.execute('''
INSERT INTO customers (first_name, last_name, email, phone, num_orders)
VALUES (?, ?, ?, ?, ?)
''', (first_name, last_name, email, phone, num_orders))
print(f"{num_records} customer records inserted successfully.")
conn.commit()
cursor.close()
Remarquez comment nous utilisons les requêtes paramétrées : au lieu de coder en dur les valeurs dans l'instruction INSERT, nous utilisons ? espaces réservés et transmettre un tuple de valeurs.
L'exécution du script devrait donner :
Output >>>
10 customer records inserted successfully.
Lecture et mise à jour des enregistrements
Maintenant que nous avons inséré les enregistrements dans la table, exécutons une requête pour lire tous les enregistrements. Remarquez comment nous utilisons la méthode execute()
pour exécuter des requêtes et la méthode fetchall()
sur le curseur pour récupérer les résultats de la requête.
Puisque nous avons stocké les résultats de la requête précédente dans `all_customers`, exécutons également une requête UPDATE pour mettre à jour le num_orders
correspondant à l'identifiant 1. Voici l'extrait de code :
import sqlite3
# Connect to the db
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Fetch and display all customers
cursor.execute('SELECT id, first_name, last_name, email, num_orders FROM customers')
all_customers = cursor.fetchall()
print("All Customers:")
for customer in all_customers:
print(customer)
# Update num_orders for a specific customer
if all_customers:
customer_id = all_customers[0][0] # Take the ID of the first customer
new_num_orders = all_customers[0][4] + 1 # Increment num_orders by 1
cursor.execute('''
UPDATE customers
SET num_orders = ?
WHERE id = ?
''', (new_num_orders, customer_id))
print(f"Orders updated for customer ID {customer_id}: now has {new_num_orders} orders.")
conn.commit()
cursor.close()
Cela génère à la fois les enregistrements et le message après la requête de mise à jour :
Output >>>
All Customers:
(1, 'Jennifer', 'Franco', 'jefferyjackson@example.org', 54)
(2, 'Grace', 'King', 'erinhorne@example.org', 43)
(3, 'Lori', 'Braun', 'joseph43@example.org', 99)
(4, 'Wendy', 'Hubbard', 'christophertaylor@example.com', 11)
(5, 'Morgan', 'Wright', 'arthur75@example.com', 4)
(6, 'Juan', 'Watson', 'matthewmeadows@example.net', 51)
(7, 'Randy', 'Smith', 'kmcguire@example.org', 32)
(8, 'Jimmy', 'Johnson', 'vwilliams@example.com', 64)
(9, 'Gina', 'Ellison', 'awong@example.net', 85)
(10, 'Cory', 'Joyce', 'samanthamurray@example.org', 41)
Orders updated for customer ID 1: now has 55 orders.
Suppression d'enregistrements
Pour supprimer un client avec un identifiant client spécifique, exécutons une instruction DELETE comme indiqué :
import sqlite3
# Specify the customer ID of the customer to delete
cid_to_delete = 3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Execute DELETE statement to remove the customer with the specified ID
cursor.execute('''
DELETE FROM customers
WHERE id = ?
''', (cid_to_delete,))
conn.commit()
f"Customer with ID {cid_to_delete} deleted successfully.")
cursor.close()
Cela produit :
Customer with ID 3 deleted successfully.
Filtrage des enregistrements à l'aide de la clause WHERE
Disons que nous souhaitons récupérer les enregistrements des clients qui ont passé moins de 10 commandes, par exemple pour lancer des campagnes ciblées, etc. Pour cela, nous exécutons une requête SELECT avec la clause WHERE précisant la condition de filtrage (en l'occurrence le nombre de commandes). Voici comment y parvenir :
import sqlite3
# Define the threshold for the number of orders
order_threshold = 10
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
# Fetch customers with less than 10 orders
cursor.execute('''
SELECT id, first_name, last_name, email, num_orders
FROM customers
WHERE num_orders < ?
''', (order_threshold,))
# Fetch all matching customers
filtered_customers = cursor.fetchall()
# Display filtered customers
if filtered_customers:
print("Customers with less than 10 orders:")
for customer in filtered_customers:
print(customer)
else:
print("No customers found with less than 10 orders.")
Et voici le résultat :
Output >>>
Customers with less than 10 orders:
(5, 'Morgan', 'Wright', 'arthur75@example.com', 4)
Conclusion
Et c’est fini ! Il s'agissait d'un guide pour démarrer avec SQLite avec Python. J'espère que vous l'avez trouvé utile. Vous pouvez trouver tout le code sur GitHub. Dans la partie suivante, nous examinerons l'exécution de jointures et de sous-requêtes, la gestion des transactions dans SQLite, et bien plus encore. En attendant, bon codage !
Si vous souhaitez savoir comment fonctionnent les index de base de données, lisez Comment accélérer les requêtes SQL à l'aide d'index [Python Edition].