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

 

 

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *