Vous êtes sur la page 1sur 39

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

elmouelhi.achref@gmail.com

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 main.py

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 127.0.0.1)
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 mysql.connector

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 mysql.connector

I c

H
ELées
U
Établissons la connexion avec la base de donn
L MO
host="localhost",
h r fE
connexion = mysql.connector.connect(
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 = connexion.cursor()
f E
hre
curseur.execute(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 = connexion.cursor()
f E
hre
curseur.execute(request)
c
c A

Récupérons le résultat

personnes = curseur.fetchall()

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
connexion.close()
curseur.close()

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 mysql.connector
from mysql.connector import Error

try:
connexion = mysql.connector.connect(
host="localhost",
user="root",
I c

password="",
database="courspython",
ELH
port=3308
U
MO
)
request = "SELECT * FROM Personne"

curseur = connexion.cursor()
f E L
hre
curseur.execute(request)

c
c A
personnes = curseur.fetchall()


for personne in personnes:
print(personne)

except Error as e:
print("Exception : ", e)

finally:
if (connexion.is_connected()):
connexion.close()
curseur.close()
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 mysql.connector
from mysql.connector import Error

try:
connexion = mysql.connector.connect(
host="localhost",
user="root",
I c

password="",
database="courspython",
ELH
port=3308
U
MO
)
request = "SELECT * FROM Personne"

f E L
curseur = connexion.cursor(dictionary=True)

hre
curseur.execute(request)

c
c A
personnes = curseur.fetchall()


for personne in personnes:
print(personne[’prenom’], personne[’nom’])

except Error as e:
print("Exception : ", e)

finally:
if (connexion.is_connected()):
connexion.close()
curseur.close()
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 = curseur.fetchmany(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 = curseur.fetchone()
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 = connexion.cursor()
ELH
U
curseur.execute(request)
L MO
re f E
c h
personne = curseur.fetchone()
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 = connexion.cursor()
I c

ELH
# virgule obligatoire
U
tuple = (2,)
L MO
curseur.execute(request, tuple)
f E
chre
c A
personne = curseur.fetchone()

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 = connexion.cursor()
I c

ELH
# virgule obligatoire
U
tuple = (2,)
L MO
curseur.execute(request, tuple)
f E
chre
c A
nom = curseur.fetchone()

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 = connexion.cursor()
ref tuple)
curseur.execute(request,
c h
c A
connexion.commit()
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
connexion.commit() est indispensable U
L M
f Epeut utiliser
Pour annuler la requête, on
r e
ch
connexion.rollback()
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 = connexion.cursor()
ref tuple)
curseur.execute(request,
c h
c A
connexion.commit()
print("Tuple inséré avec succès dans la table
personne avec id = ", curseur.lastrowid)

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 = connexion.cursor() M
f E L tuples)
c h re
curseur.executemany(request,

c A

connexion.commit()
print(curseur.rowcount, "tuple(s) inséré(s) avec succès
dans la table personne", curseur.lastrowid)

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

myconnection.py
I
ELH config.json

U config.py

MO
dao

f EL init .py

chre dao.py

c A
model
personnedao.py

init .py
personne.py
main.py

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 config.json
{
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 config.py qui charge les données définies dans


config.json
I c

import json ELH
U
L MO
config = {}
f E
chre
c A
with open(’src/config/config.json’) as f:

config = json.load(f)

H & H: Research and Training 28 / 34


Restructuration du code

Python
La classe MyConnection

import mysql.connector as pymysql


from mysql.connector 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 = pymysql.connect(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
@num.setter

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
@nom.setter

c
c A
def nom(self, nom) -> None:
self._nom = nom
@property

def prenom(self) -> str:
return self._prenom
@prenom.setter
def prenom(self, prenom) -> None:
self._prenom = prenom
@prenom.deleter
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 ..config.myconnection import MyConnection


from ..model.personne 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 main.py pour tester toutes ces classes


from mysql.connector import Error
from src.dao.personnedao import PersonneDao
I c

from src.model.personne import Personne
ELH
U
try:
L MO
f E
hre
personneDao = PersonneDao()
c
for personne in personneDao.findAll():
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

Vous aimerez peut-être aussi