Python : connexion à une base MySQL
Achref El Mouelhi
Docteur de l’université d’Aix-Marseille
Chercheur en programmation par contrainte (IA)
Ingénieur en génie logiciel
[Link]@[Link]
H & H: Research and Training 1 / 34
Plan
1 Introduction
2 Téléchargement et installation
3 Avant de commencer
4 Utilisation
5 Restructuration du code
H & H: Research and Training 2 / 34
Introduction
Python
Pour se connecter à une base de données
Il nous faut un driver (qui varie selon le SGBD utilisé)
I c
SGBD : Système de Gestion de Bases de Données
ELH
U
L MO
f E
chre
c A
H & H: Research and Training 3 / 34
Introduction
Python
Pour se connecter à une base de données
Il nous faut un driver (qui varie selon le SGBD utilisé)
I c
EL
SGBD : Système de Gestion de Bases de Données H
U
L MO
f E
Driver ? A c hre
c
Une API (interface d’application)
Facilitant l’accès aux données gérées par un SGBD
H & H: Research and Training 3 / 34
Téléchargement et installation
Python
Téléchargement et installation
Définissez une variable d’environnement pour pip (défini dans I c
C:\Users\elmou\AppData\Local\Programs\Python ELH
U
\Python38-32\Scripts)
L MO
f E
hre
Redémarrez la console
c
c A
Lancez la commande pip install
mysql-connector-python
H & H: Research and Training 4 / 34
Avant de commencer
Python
Démarche
I c
ELH
Créez un répertoire cours-python-mysql dans votre espace
U
MO
de travail
f E L
Lancez VSC et allez dans File > Open Folder... et
c hre
choisissez cours-python-mysql
A
c
Dans cours-python-mysql, créez un fichier [Link]
H & H: Research and Training 5 / 34
Avant de commencer
Python
Voici le script SQL qui permet de créer la base de données utilisée dans ce
cours
CREATE DATABASE courspython;
USE courspython;
I c
E LH
CREATE TABLE personne(
num INT PRIMARY KEY AUTO_INCREMENT, OU
L M
nom VARCHAR(30),
prenom VARCHAR(30)
ref E
);
c h
c A
SHOW TABLES;
INSERT INTO personne (nom, prenom) VALUES ("Wick", "John"),
("Dalton", "Jack");
SELECT * FROM personne;
H & H: Research and Training 6 / 34
Utilisation
Python
Quatre étapes
I c
éesL
Établir la connexion avec la base de donnE H
O U
Créer et exécuter des requêtes M
fE L SQL
h r
Récupérer le résultate
Fermer
Ac
cla connexion
H & H: Research and Training 7 / 34
Utilisation
Python
Se connecter à la base de données
I c
le nom de l’hôte sur lequel le serveur MySQL est installé (dans
notre cas localhost ou [Link])
EL H
U
Odéfaut 3306 ou 3308)
le port TCP/IP utilisé par MySQL
L M(par
le nom de la base de
h r e f Eées MySQL
donn
le nom
Ac (par défaut root pour MySQL)
cd’utilisateur
le mot de passe
H & H: Research and Training 8 / 34
Utilisation
Python
Importons le module de connexion
import [Link]
I c
ELH
U
L MO
f E
chre
c A
H & H: Research and Training 9 / 34
Utilisation
Python
Importons le module de connexion
import [Link]
I c
H
ELées
U
Établissons la connexion avec la base de donn
L MO
host="localhost",
h r fE
connexion = [Link](
e
user="root", A c
c
password="",
database="courspython",
port=3308
)
H & H: Research and Training 9 / 34
Utilisation
Python
Créons la requête
request = "SELECT * FROM personne"
I c
ELH
U
L MO
f E
chre
c A
H & H: Research and Training 10 / 34
Utilisation
Python
Créons la requête
request = "SELECT * FROM personne"
I c
ELH
Exécutons la requête
U
L MO
curseur = [Link]()
f E
hre
[Link](request)
c
c A
H & H: Research and Training 10 / 34
Utilisation
Python
Créons la requête
request = "SELECT * FROM personne"
I c
ELH
Exécutons la requête
U
L MO
curseur = [Link]()
f E
hre
[Link](request)
c
c A
Récupérons le résultat
personnes = [Link]()
H & H: Research and Training 10 / 34
Utilisation
Python
Affichons le résultat
for personne in personnes:
print(personne)
I c
# résultat ELH
U
# (1, ’Wick’, ’John’)
L MO
# (2, ’Dalton’, ’Jack’)
f E
chre
c A
H & H: Research and Training 11 / 34
Utilisation
Python
Affichons le résultat
for personne in personnes:
print(personne)
I c
# résultat ELH
U
# (1, ’Wick’, ’John’)
L MO
# (2, ’Dalton’, ’Jack’)
f E
A c hre
c
Et enfin fermons la connexion
[Link]()
[Link]()
H & H: Research and Training 11 / 34
Utilisation
Python
Les instructions d’accès aux données peuvent lever une exception. Ajoutons donc try ... except ... finally
import [Link]
from [Link] import Error
try:
connexion = [Link](
host="localhost",
user="root",
I c
password="",
database="courspython",
ELH
port=3308
U
MO
)
request = "SELECT * FROM Personne"
curseur = [Link]()
f E L
hre
[Link](request)
c
c A
personnes = [Link]()
for personne in personnes:
print(personne)
except Error as e:
print("Exception : ", e)
finally:
if (connexion.is_connected()):
[Link]()
[Link]()
print("La connexion à MySQL est désormais fermée")
H & H: Research and Training 12 / 34
Utilisation
Python
Pour afficher certains champs
I c
for personne in personnes:
print(personne[1], personne[2]) ELH
U
L MO
# affiche
f E
# Wick John
chre
#
#
Dalton Jack
c A
La connexion à MySQL est désormais fermée
H & H: Research and Training 13 / 34
Utilisation
Python
Les instructions d’accès aux données peuvent lever une exception. Ajoutons donc try ... except ... finally
import [Link]
from [Link] import Error
try:
connexion = [Link](
host="localhost",
user="root",
I c
password="",
database="courspython",
ELH
port=3308
U
MO
)
request = "SELECT * FROM Personne"
f E L
curseur = [Link](dictionary=True)
hre
[Link](request)
c
c A
personnes = [Link]()
for personne in personnes:
print(personne[’prenom’], personne[’nom’])
except Error as e:
print("Exception : ", e)
finally:
if (connexion.is_connected()):
[Link]()
[Link]()
print("La connexion à MySQL est désormais fermée")
H & H: Research and Training 14 / 34
Utilisation
Python
Pour indiquer le nombre de tuples à récupérer, on utilise
fetchmany(nombre)
I c
personnes = [Link](1)
ELH
for personne in personnes: MO
U
f E L
c h re
print(personne[1], personne[2])
# affichec A
# Wick John
H & H: Research and Training 15 / 34
Utilisation
Python
Pour récupérer seulement le premier tuple, on utilise fetchone()
I c
personne = [Link]()
ELH
U
MO
print(personne[1], personne[2])
L
h r e fE
# affiche
A c
c
# Wick John
H & H: Research and Training 16 / 34
Utilisation
Python
Pour récupérer un tuple selon la valeur d’une colonne (num = 2
par exemple)
request = "SELECT * FROM Personne WHERE num = 2"
I c
curseur = [Link]()
ELH
U
[Link](request)
L MO
re f E
c h
personne = [Link]()
c A
print(personne[1], personne[2])
# affiche
# Dalton Jack
H & H: Research and Training 17 / 34
Utilisation
Python
Ou en utilisant les requêtes paramétrées
request = "SELECT * FROM Personne WHERE num = %s"
curseur = [Link]()
I c
ELH
# virgule obligatoire
U
tuple = (2,)
L MO
[Link](request, tuple)
f E
chre
c A
personne = [Link]()
print(personne[1], personne[2])
# affiche
# Dalton Jack
H & H: Research and Training 18 / 34
Utilisation
Python
Pour sélectionner seulement quelques champs d’un tuple
request = "SELECT nom FROM Personne WHERE num = %s"
curseur = [Link]()
I c
ELH
# virgule obligatoire
U
tuple = (2,)
L MO
[Link](request, tuple)
f E
chre
c A
nom = [Link]()
print(nom[0])
# affiche
# Dalton
H & H: Research and Training 19 / 34
Utilisation
Python
Pour faire une insertion
request = """INSERT INTO personne (nom, prenom)
I c
VALUES (%s, %s) """
ELH
tuple = (’muller’, ’thomas’) OU
L M
E
curseur = [Link]()
ref tuple)
[Link](request,
c h
c A
[Link]()
print("Tuple inséré avec succès dans la table
personne")
H & H: Research and Training 20 / 34
Utilisation
Python
I
c
Remarques
H
L valider la requête
Epour
O
[Link]() est indispensable U
L M
f Epeut utiliser
Pour annuler la requête, on
r e
ch
[Link]()
A
c
H & H: Research and Training 21 / 34
Utilisation
Python
Pour récupérer la valeur de la clé primaire auto-générée
request = """INSERT INTO personne (nom, prenom)
I c
VALUES (%s, %s) """
ELH
tuple = (’muller’, ’thomas’) OU
L M
E
curseur = [Link]()
ref tuple)
[Link](request,
c h
c A
[Link]()
print("Tuple inséré avec succès dans la table
personne avec id = ", [Link])
H & H: Research and Training 22 / 34
Utilisation
Python
Pour une insertion multiple
request = """INSERT INTO personne (nom, prenom)
I c
H
VALUES (%s, %s) """
tuples = [(’muller’, ’thomas’), O UEL ’franc’)]
(’ribery’,
curseur = [Link]() M
f E L tuples)
c h re
[Link](request,
c A
[Link]()
print([Link], "tuple(s) inséré(s) avec succès
dans la table personne", [Link])
H & H: Research and Training 23 / 34
Utilisation
Python
I c
EL H
Exercice
U
L MetODELETE.
Pour terminer le CRUD, faites UPDATE
h r e fE
A c
c
H & H: Research and Training 24 / 34
Restructuration du code
Python
Organisation du code
Placer toutes les données (nomBaseDeDonnées, nomUtilisateur,
I
c
motDePasse...) dans un fichier JSON et les charger dans une
classe MyConnection EL H
O U
Pour chaque table de la base deM
L données, définir une classe
f Eayant comme attributs les colonnes de
Python (appelée model)
c h r e
cette table
c A
Placer
tout le code correspondant à l’accès aux données (de la
base de données) dans des nouvelles classes (qui constitueront
la couche DAO : Data Access Object)
H & H: Research and Training 25 / 34
Restructuration du code
cours-python-mysql
src
config
init .py
c
[Link]
I
ELH [Link]
U [Link]
MO
dao
f EL init .py
chre [Link]
c A
model
[Link]
init .py
[Link]
[Link]
Arborescence du projet ( init .py n’est plus nécessaire depuis Python 3.3)
H & H: Research and Training 26 / 34
Restructuration du code
Python
Le fichier [Link]
{
I c
"mysql": {
ELH
"host": "localhost",
U
"user": "root",
L MO
"password": "",
f E
chre
"db": "courspython",
}
c A
"port": 3308
H & H: Research and Training 27 / 34
Restructuration du code
Python
Le fichier [Link] qui charge les données définies dans
[Link]
I c
import json ELH
U
L MO
config = {}
f E
chre
c A
with open(’src/config/[Link]’) as f:
config = [Link](f)
H & H: Research and Training 28 / 34
Restructuration du code
Python
La classe MyConnection
import [Link] as pymysql
from [Link] import Error
from .config import config
class MyConnection:
I c
__connection = None
ELH
__cursor = None
U
def __init__(self):
L MO
E
__db_config = config[’mysql’]
f
hre
self.__connection = [Link](host=__db_config[’host’],
user = __db_config[’user’],
c password = __db_config[’password’],
c A
db = __db_config[’db’],
port=__db_config[’port’])
self.__cursor = self.__connection.cursor()
def query(self, query, params):
self.__cursor.execute(query, params)
return self.__cursor
def close(self):
self.__connection.close()
H & H: Research and Training 29 / 34
Restructuration du code
La classe Personne
class Personne:
def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
self._num = num
self._nom = nom
self._prenom = prenom
@property
def num(self) -> int:
return self._num
@[Link]
I c
H
def num(self, num) -> None:
EL
if num > 0:
self._num = num
U
MO
else:
self._num = 0
@property
def nom(self) -> str:
f E L
hre
return self._nom
@[Link]
c
c A
def nom(self, nom) -> None:
self._nom = nom
@property
def prenom(self) -> str:
return self._prenom
@[Link]
def prenom(self, prenom) -> None:
self._prenom = prenom
@[Link]
def prenom(self) -> str:
del self._prenom
def __str__(self) -> str:
return str(self._num) + " " + self._prenom + " " + self._nom
H & H: Research and Training 30 / 34
Restructuration du code
Python
La classe abstraite Dao
from typing import TypeVar, Generic, Iterable
from abc import ABC, abstractmethod
T = TypeVar(’T’)
I c
class Dao (Generic[T], ABC):
@abstractmethod
ELH
U
MO
def save(self, t: T) -> T:
pass
@abstractmethod
f E L
hre
def findAll(self) -> Iterable:
pass
c
c A
@abstractmethod
def findById(self, t: int) -> T:
pass
@abstractmethod
def update(self, t: T) -> T:
pass
@abstractmethod
def remove(self, t: T) -> None:
pass
H & H: Research and Training 31 / 34
Restructuration du code
La classe PersonneDao qui implémente Dao[Personne]
from ..[Link] import MyConnection
from ..[Link] import Personne
from .dao import Dao
class PersonneDao (Dao[Personne]):
__db = None
I c
def __init__(self):
self.__db = MyConnection()
ELH
U
def findAll(self):
L MO
f E
return self.__db.query("SELECT * FROM personne", None).fetchall
hre
()
c
c A
def save(self, personne: Personne) -> Personne:
pass
def findById(self, t: int) -> Personne:
pass
def update(self, t: Personne) -> Personne:
pass
def remove(self, t: Personne) -> None:
pass
H & H: Research and Training 32 / 34
Restructuration du code
Python
Le [Link] pour tester toutes ces classes
from [Link] import Error
from [Link] import PersonneDao
I c
from [Link] import Personne
ELH
U
try:
L MO
f E
hre
personneDao = PersonneDao()
c
for personne in [Link]():
c A
print(personne)
except Error as e:
print("Exception : ", e)
H & H: Research and Training 33 / 34
Restructuration du code
Python
I
c
Remarque
EL H
U
Oautres méthodes de la classe
M
N’oublions pas d’implémenter les quatre
L
abstraite Dao
h r e fE
A c
c
H & H: Research and Training 34 / 34