Accéder à une base de données avec Flask
Comment gérer une base de données avec un serveur Web Python Flask ?
Bibliothèque Flask (voir Python Flask)
pip install Flask
https://flask.palletsprojects.com/en/2.2.x/appcontext/
Avec SQLite
Bibliothèque sqlite3 :
pip install pysqlite3
Les bases de données SQLite sont enregistrés dans des fichiers db
enregistrés sur le serveur.
Connexion à la base
Afin de conserver une instance de la connexion à la base durant la durée d’une requête HTTP (appelés session), on peut utiliser le contexte de l’application Flask :
import sqlite3 from flask import g # g est une variable de contexte, pour stocker des données pendant un contexte d'application DATABASE = 'chemin_vers/ma_base.db' def get_db(): db = getattr(g, '_database', None) if db is None: # la base de données n'est pas encore mémorisée dans le contexte db = g._database = sqlite3.connect(DATABASE) db.row_factory = sqlite3.Row return db # Pour s'assurer que la connexion à la base est bien fermée # à la fermeture du contexte (fin de la session) @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) if db is not None: db.close()
Accès aux données
Ainsi, dans chaque fonction de traitement des requêtes, on peut utiliser get_db()
pour obtenir la connexion actuelle ouverte à la base de données.
Pour exécuter des requêtes SQL, on créé deux fonctions dédiées :
def read_db(query, args=(), one=False): cur = get_db().execute(query, args) rv = cur.fetchall() cur.close() return (rv[0] if rv else None) if one else rv def write_db(query, args=()): db = get_db() cur = db.execute(query, args) db.commit() cur.close()
La fonction read_db
renvoie une unique « ligne » (si one==True
), ou bien une liste de « lignes », de type sqlite3.Row
, un type d’objet pouvant se comporter comme une liste ET comme un dictionnaire :
Exemple : si r
est une ligne sqlite3.Row
comportant 3 champs 'nom'
, 'email'
et 'mdp'
:
>>> # Accès par le nom du champ >>> r['nom'] Blaise >>> # Accès par l'indice du champ >>> r[0] Blaise >>> # Itération sur tous les champs >>> for v in r: ... print(v) Blaise blaise.pascal@blaisepascal.fr 1234
Les requêtes doivent être passées sous forme d’une chaîne de caractères, les arguments placés dans un tuple. Leurs emplacements dans la chaîne de caractères sont repérés par le caractère ?
.
Exemples :
read_db("SELECT * FROM users WHERE email=?", (email,), one = True) write_db("INSERT INTO users VALUES (?,?,?)", (nom, email, hmdp))
Avec MySQL
Bibliothèque mysql-connector :
pip install mysql-connector-python
Les bases de données MySQL sont gérées par un serveur MySQL installé sur le serveur (pour Raspberry, voir Installer un serveur web Python).
Connexion à la base
Afin de conserver une instance de la connexion à la base durant la durée d’une requête HTTP, on peut utiliser le contexte de l’application Flask :
import mysql.connector from flask import g # g est une variable de contexte, pour stocker des données pendant un contexte d'application DATABASE = 'ma_base' def get_db(): db = getattr(g, '_database', None) if db is None: # la base de données n'est pas encore mémorisée dans le contexte db = g._database = mysql.connector.connect(host="localhost", user="pi", password="raspberryNS1", database=DATABASE) return db @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) if db is not None: db.close()
Accès aux données
Ainsi, dans chaque fonction de traitement des requêtes, on peut utiliser get_db()
pour obtenir la connexion actuelle ouverte à la base de données.
Pour exécuter des requêtes SQL, on créé deux fonctions dédiées :
def read_db(query, args=(), one=False): cur = get_db().cursor() cur.execute(query, args) rv = cur.fetchall() cur.close() return (rv[0] if rv else None) if one else rv def write_db(query, args=()): db = get_db() cur = db.execute(query, args) db.commit()
La fonction read_db
renvoie une unique « ligne » (si one==True
), ou bien une liste de « lignes », de type sqlite3.Row
, un type d’objet pouvant se comporter comme une liste ET comme un dictionnaire :
Exemple : si r
est une ligne sqlite3.Row
comportant 3 champs 'nom'
, 'email'
et 'mdp'
:
>>> # Accès par le nom du champ >>> r['nom'] Blaise >>> # Accès par l'indice du champ >>> r[0] Blaise >>> # Itération sur tous les champs >>> for v in r: ... print(v) Blaise blaise.pascal@blaisepascal.fr 1234
Les requêtes doivent être passées sous forme d’une chaîne de caractères, les arguments placés dans un tuple. Leurs emplacements dans la chaîne de caractères sont repérés par la chaîne %s
.
Exemples :
read_db("SELECT * FROM users WHERE email=%s", (email,), one = True) write_db("INSERT INTO users VALUES (%s,%s,%s)", (nom, email, hmdp))
Utilisation de SQLalchémy
…