Accès à une base de données

Pour accéder à une base de données avec Python, il faut instancier un connecteur, puis établir une connexion, puis exécuter des requête à l’aide d’un curseur;

Voir Les bases de données avec Python

La connexion et le curseur doivent être fermés après utilisation afin de libérer la ressource.

 

Le protocole HTTP état sans état (chaque requête est indépendante), dans une application Web, la partie Python du programme est lancée plusieurs fois, à chaque requête HTTP de la part du client notamment.

Il faut donc s’assurer :

  1. qu’on n’ouvre pas plusieurs connexions à la base de données en même temps
  2. qu’on ferme bien la connexion lorsque le contexte d’exécution de Flask se ferme

 

Avec SQLite

Installation

Bibliothèque sqlite3 :

pip install pysqlite3

 

Utilisation

Les bases de données SQLite sont enregistrés dans des fichiers db enregistrés sur le serveur.

Les notions sont similaires aux autres SGBD :

  1. Création d’une connexion à la base : db = sqlite3.connect('fichier.db')
  2. Création d’un curseur : cur = db.cursor()
  3. Envoi d’une requête à l’aide du curseur : cur.execute(requete, arguments)
  4. Récupération de la réponse : r = cur.fetchall()
    ou bien confirmation des changements : db.commit()
  5. Fermeture de la connexion : db.close()

 

 

Connexion à la base

Rappel

Le protocole HTTP est sans état, ce qui signifie qu’il ne mémorise aucune information entre deux requêtes.

Afin de conserver certaines informations entre deux requêtes, il faut les mettre en mémoire sur le navigateur du client, sous forme de cookies, chiffrés !

 

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 sqlite3
from flask import Flask, g 
# g est une variable de contexte, pour stocker des données pendant un contexte d'application

app = Flask(__name__)
app.config['DATABASE'] = 'chemin_vers/ma_base.db'

def get_db():
    if '_database' not in g: # la base de données n'est pas encore mémorisée dans le contexte
        g._database = sqlite3.connect(current_app.config['DATABASE'])
        g._database.row_factory = sqlite3.Row
    return g._database

# 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 = g.pop('_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 *