9. Utilizzo di SGBD MySQL
![]() |
9.1. Installazione del modulo MySQLdb
Scriveremo degli script utilizzando un database MySQL:
![]() |
Le funzioni Python per la gestione di un database MySQL sono incapsulate in un modulo MySQLdb che non è incluso nella distribuzione iniziale di Python. È quindi necessario scaricare e installare il modulo. Ecco come procedere:
![]() |
- nel menu dei programmi, selezionare [1], il gestore dei pacchetti Python. Apparirà quindi la finestra di comando [2].
Cercare la parola chiave mysql tra i pacchetti:
C:\Documents and Settings\st>pypm search mysql
Get: [pypm-be.activestate.com] :repository-index:
Get: [pypm-free.activestate.com] :repository-index:
autosync: synced 2 repositories
chartio Setup wizard and connection client for connecting
chartio-setup Setup wizard and connection client for connecting
cns.recipe.zmysqlda Recipe for installing ZMySQLDA
collective.recipe.zmysqlda Recipe for installing ZMySQLDA
django-mysql-manager DESCRIPTION_DESCRIPTION_DESCRIPTION
jaraco.mysql MySQLDB-compatible MySQL wrapper by Jason R. Coomb
lovely.testlayers mysql, postgres nginx, memcached cassandra test la
mtstat-mysql MySQL Plugins for mtstat
mysql-autodoc Generate HTML documentation from a mysql database
mysql-python Python interface to MySQL
mysqldbda MySQL Database adapter
products.zmysqlda MySQL Zope2 adapter.
pymysql Pure Python MySQL Driver
pymysql-sa PyMySQL dialect for SQLAlchemy.
pymysql3 Pure Python MySQL Driver
sa-mysql-dt Alternative implementation of DateTime column for
schemaobject Iterate over a MySQL database schema as a Python o
schemasync A MySQL Schema Synchronization Utility
simplestore A datastore layer built on top of MySQL in Python.
sqlbean A auto maping ORM for MYSQL and can bind with memc
sqlwitch sqlwitch offers idiomatic SQL generation on top of
tiddlywebplugins.mysql MySQL-based store for tiddlyweb
tiddlywebplugins.mysql2 MySQL-based store for tiddlyweb
zest.recipe.mysql A Buildout recipe to setup a MySQL database.
Sono stati elencati tutti i moduli il cui nome o la cui descrizione contengono la parola chiave mysql. Quello che ci interessa è [mysql-python], riga 14. Lo installiamo:
C:\Documents and Settings\st>pypm install mysql-python
The following packages will be installed into "%APPDATA%\Python" (2.7):
mysql-python-1.2.3
Hit: [pypm-free.activestate.com] mysql-python 1.2.3
Installing mysql-python-1.2.3
C:\Documents and Settings\st>echo %APPDATA%
C:\Documents and Settings\st\Application Data
- riga 5: il pacchetto mysql-python-1.2.3 è stato installato nella cartella "%APPDATA%\Python", dove APPDATA è la cartella indicata alla riga 8.
Questa operazione potrebbe non andare a buon fine se:
- l'interprete Python utilizzato è una versione a 64 bit;
- il percorso %APPDATA% contiene caratteri accentati.
9.2. Installazione di MySQL
Esistono diversi modi per installare SGBD MySQL. In questo caso abbiamo utilizzato WampServer, un pacchetto che riunisce diversi software:
- un server web Apache, che useremo per scrivere script web in Python;
- il SGBD MySQL;
- il linguaggio di scripting PHP;
- uno strumento di amministrazione del SGBD MySQL scritto in PHP: phpMyAdmin.
WampServer può essere scaricato (giugno 2011) al seguente indirizzo:
![]() |
- in [1], si scarica la versione corretta di WampServer;
- per [2], una volta installato, lo si avvia. Ciò avvierà il server Web Apache e SGBD MySQL;
- in [3], una volta avviato, WampServer può essere gestito tramite un'icona [3] situata in basso a destra sulla barra delle applicazioni;
- in [4], si avvia lo strumento di amministrazione di MySQL.
Si crea un database [dbpersonnes]:

Si crea un utente [admpersonnes] con la password [nobody]:
![]() | ![]() |
![]() |
- in [1], il nome dell'utente;
- in [2], il computer di SGBD su cui gli vengono concessi i diritti;
- in [3], la sua password [nobody];
- in [4], idem;
- in [5], non si assegnano diritti a questo utente;
- in [6], lo si crea.
![]() |
- in [7], si torna alla pagina iniziale di phpMyAdmin;
- in [8], si utilizza il link [Privileges] di questa pagina per modificare quelli dell'utente [admpersonnes] e [9].
![]() |
- in [10], si indica che si desidera assegnare all’utente [admpersonnes] i diritti sul database [dbpersonnes];
- in [11], si conferma la scelta.
![]() |
- con il collegamento [12] [Tout cocher], si concedono all'utente [admpersonnes] tutti i diritti sul database [dbpersonnes] [13];
- si conferma in [14].
Ora abbiamo:
- un database MySQL e [dbpersonnes];
- un utente [admpersonnes / nobody] che dispone di tutti i diritti su questo database.
Scriveremo degli script Python per utilizzare il database.
9.3. Connessione a un database MySQL - 1
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# connessione a un database MySQL
....
Note:
- righe 2-4: gli script che contengono operazioni con SGBD e MySQL devono importare il modulo MySQLdb. Ricordiamo che abbiamo installato questo modulo nella cartella [%APPDATA%\Python]. La cartella [%APPDATA%\Python] viene automaticamente scansionata quando un codice Python richiede un modulo. In realtà vengono scansionate tutte le cartelle dichiarate in sys.path. Ecco un esempio che visualizza queste cartelle:
# -*- coding=utf-8 -*-
import sys
# visualizzazione delle cartelle di sys.path
for dossier in sys.path:
print dossier
La visualizzazione sullo schermo è la seguente:
Riga 8, la cartella [site-packages] dove era stato inizialmente installato MySQLdb. Spostiamo la cartella [site-packages], che è la cartella in cui l’utilità pypm installa i moduli Python. Per aggiungere una nuova cartella che Python esplorerà alla ricerca dei moduli, la aggiungiamo all’elenco sys.path:
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# connessione a un database MySQL
....
Alla riga 3, si aggiunge la cartella in cui è stato spostato il modulo MySQLdb.
Il codice completo dell'esempio è il seguente:
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# connessione a un database MySQL
# l'identità dell'utente è (admpersonnes,nobody)
user="admpersonnes"
pwd="nobody"
host="localhost"
connexion=None
try:
print "connexion..."
# connessione
connexion=MySQLdb.connect(host=host,user=user,passwd=pwd)
# monitoraggio
print "Connexion a MySQL reussie sous l'identite host={0},user={1},passwd={2}".format(host,user,pwd)
except MySQLdb.OperationalError,message:
print "Erreur : {0}".format(message)
finally:
try:
connexion.close()
except:
pass
- righe 8-11: lo script effettuerà il collegamento (riga 15) dell'utente [admpersonnes / nobody] a SGBD MySQL della macchina [localhost]. Non lo si collega a un database specifico;
- righe 12-24: la connessione potrebbe non andare a buon fine. Pertanto, viene eseguita all’interno di un blocco try / except / finally;
- riga 15: il metodo connect del modulo MySQLdb accetta diversi parametri denominati:
- user: utente proprietario della connessione [admpersonnes];
- pwd: password dell'utente [nobody];
- host: macchina del SGBD MySQL [localhost];
- db: il database a cui ci si connette. Facoltativo.
- riga 18: se viene generata un'eccezione, questa è di tipo [ MySQLdb.OperationalError] e il messaggio di errore associato si troverà nella variabile [message];
- righe 20-23: nella clausola [finally] si chiude la connessione. In caso di eccezione, questa viene intercettata (riga 23) ma non viene intrapresa alcuna azione (riga 24).
connexion...
Connexion a MySQL reussie sous l'identite host=localhost,user=admpersonnes,passwd=nobody
9.4. Connessione a un database MySQL - 2
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# ---------------------------------------------------------------------------------
def testeConnexion(hote,login,pwd):
# effettua l'accesso e poi la disconnessione (login, pwd) al database MySQL del server host
# genera l'eccezione MySQLdb.operationalError
# connessione
connexion=MySQLdb.connect(host=hote,user=login,passwd=pwd)
print "Connexion a MySQL reussie sous l'identite (%s,%s,%s)" % (hote,login,passwd)
# la connessione viene chiusa
connexion.close()
print "Fermeture connexion MySQL reussie\n"
# ---------------------------------------------- main
# connessione al database MySQL
# identità dell'utente
user="admpersonnes"
passwd="nobody"
host="localhost"
# test di connessione
try:
testeConnexion(host,user,passwd)
except MySQLdb.OperationalError,message:
print message
# con un utente inesistente
try:
testeConnexion(host,"xx","xx")
except MySQLdb.OperationalError,message:
print message
Note:
- righe 7-15: una funzione che tenta di connettere e poi disconnettere un utente a un SGBD MySQL. Visualizza il risultato;
- righe 18-34: programma principale – chiama due volte il metodo testeConnexion e visualizza eventuali eccezioni.
9.5. Creazione di una tabella MySQL
Ora che sappiamo come creare una connessione con un SGBD MySQL, iniziamo a inviare comandi SQL su questa connessione. A tal fine, ci collegheremo al database creato [dbpersonnes] e utilizzeremo la connessione per creare una tabella all’interno del database.
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# ---------------------------------------------------------------------------------
def executeSQL(connexion,update):
# esegue una richiesta di aggiornamento sulla connessione
# viene richiesto un cursore
curseur=connexion.cursor()
# esegue la query SQL sulla connessione
try:
curseur.execute(update)
connexion.commit()
except Exception, erreur:
connexion.rollback()
raise
finally:
curseur.close()
# ---------------------------------------------- main
# connessione al database MySQL
# l'identità dell'utente
ID="admpersonnes"
PWD="nobody"
# il computer host del SGBD
HOTE="localhost"
# identificativo del database
BASE="dbpersonnes"
# connessione
try:
connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,message:
print message
sys.exit()
# eliminazione della tabella «persone» se esiste
# se non esiste, verrà generato un errore
# viene ignorato
requete="drop table personnes"
try:
executeSQL(connexion,requete)
except:
pass
# creazione della tabella "persone"
requete="create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom))"
try:
executeSQL(connexion,requete)
except MySQLdb.OperationalError,message:
print message
sys.exit()
# si disconnette e si esce
try:
connexion.close()
except MySQLdb.OperationalError,message:
print message
sys.exit()
Note:
- riga 7: la funzione executeSQL esegue una query SQL su una connessione aperta;
- riga 10: le operazioni SQL sulla connessione vengono eseguite tramite un oggetto specifico denominato cursore;
- riga 10: acquisizione di un cursore;
- riga 13: esecuzione della query SQL;
- riga 14: la transazione corrente viene confermata;
- riga 15: in caso di eccezione, il messaggio di errore viene memorizzato nella variabile errore;
- riga 16: la transazione corrente viene annullata;
- riga 17: l'eccezione viene rilanciata;
- riga 19: indipendentemente dalla presenza o meno di un errore, il cursore viene chiuso. Ciò libera le risorse ad esso associate.
create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom)) : requete reussie
Verifica con phpMyAdmin:
![]() |
- il database [dbpersonnes] [1] contiene una tabella [personnes] [2] che presenta la struttura [3] e la chiave primaria [4].
9.6. Inserimento dei dati nella tabella [personnes]
Dopo aver creato in precedenza la tabella [personnes], ora la popoliamo.
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# altri moduli
import re
# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
# utilizza la connessione (HOTE,ID,PWD,BASE)
# esegue su questa connessione i comandi SQL contenuti nel file di testo SQL
# questo file è un file di comandi SQL da eseguire al ritmo di uno per riga
# se «seguito=True», ogni esecuzione di un comando SQL viene accompagnata da un messaggio che ne indica il successo o il fallimento
# se «arresto=True», la funzione si interrompe al primo errore riscontrato; in caso contrario, esegue tutti i comandi SQL
# la funzione restituisce un elenco (numero di errori, errore1, errore2, ...)
# si verifica la presenza del file SQL
data=None
try:
data=open(SQL,"r")
except:
return [1,"Le fichier %s n'existe pas" % (SQL)]
# connessione
try:
connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,erreur:
return [1,"Erreur lors de la connexion a MySQL sous l'identite (%s,%s,%s,%s) : %s" % (HOTE, ID, PWD, BASE, erreur)]
# si richiede un cursore
curseur=connexion.cursor()
# esecuzione delle query SQL contenute nel file SQL
# vengono inserite in un array
requetes=data.readlines()
# le si eseguono una alla volta - inizialmente nessun errore
erreurs=[0]
for i in range(len(requetes)):
# si memorizza la richiesta corrente
requete=requetes[i]
# la query è vuota? Se sì, si passa alla query successiva
if re.match(r"^\s*$",requete):
continue
# esecuzione della query i
erreur=""
try:
curseur.execute(requete)
except Exception, erreur:
pass
#si è verificato un errore?
if erreur:
# Un altro errore
erreurs[0]+=1
# messaggio di errore
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# monitoraggio dello schermo o no?
if suivi:
print msg
# ci fermiamo?
if arret:
return erreurs
else:
if suivi:
print "%s : Execution reussie" % (requete)
# chiusura della connessione e liberazione delle risorse
curseur.close()
connexion.commit()
# si disconnette
try:
connexion.close()
except MySQLdb.OperationalError,erreur:
# un altro errore
erreurs[0]+=1
# messaggio di errore
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# ritorno
return erreurs
# ---------------------------------------------- main
# connessione al database MySQL
# identità dell'utente
ID="admpersonnes"
PWD="nobody"
# il computer host del SGBD
HOTE="localhost"
# identificativo del database
BASE="dbpersonnes"
# identificativo del file di testo contenente i comandi SQL da eseguire
TEXTE="sql.txt";
# creazione e compilazione della tabella
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
#visualizzazione del numero di errori
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
print erreurs[i]
Il file sql.txt:
È stato inserito intenzionalmente un errore alla riga 5.
Risultati sullo schermo:
drop table personnes : Execution reussie
create table personnes (prenom varchar(30) not null, nom varchar(30) not null, age integer not null, primary key (nom,prenom)) : Execution reussie
insert into personnes values('Paul','Langevin',48) : Execution reussie
insert into personnes values ('Sylvie','Lefur',70) : Execution reussie
xx : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx' at
line 1"))
insert into personnes values ('Pierre','Nicazou',35) : Execution reussie
insert into personnes values ('Geraldine','Colou',26) : Execution reussie
insert into personnes values ('Paulette','Girond',56) : Execution reussie
il y a eu 1 erreur(s)
xx : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx' at line 1"))
Verifica con phpMyAdmin:

- in [1], il collegamento [Afficher] consente di ottenere il contenuto della tabella [personnes] [2].
9.7. Esecuzione di query SQL a scelta
Il seguente script consente di eseguire un file di comandi SQL e di visualizzare il risultato di ciascuna di esse:
- il risultato di SELECT se il comando è SELECT;
- il numero di righe modificate se il comando è INSERT, UPDATE, DELETE.
# importazione del modulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# altri moduli
import re
def cutNewLineChar(ligne):
# rimuove il carattere di fine riga da [ligne], se presente
l=len(ligne)
while(ligne[l-1]=="\n" or ligne[l-1]=="\r"):
l-=1
return(ligne[0:l])
# ---------------------------------------------------------------------------------
def afficherInfos(curseur):
# visualizza il risultato di una query SQL
# si trattava di un SELECT?
if curseur.description:
# c'è una descrizione, quindi si tratta di un SELECT
# descrizione[i] è la descrizione della colonna n. i del SELECT
# descrizioneQZXW2HTMLBW2ldZQXQZXW2HTMLBWzBdZQX è il nome della colonna n. i del select
# vengono visualizzati i nomi dei campi
titre=""
for i in range(len(curseur.description)):
titre+=curseur.description[i][0]+","
# viene visualizzato l'elenco dei campi senza la virgola finale
print titre[0:len(titre)-1]
# riga di separazione
print "-"*(len(titre)-1)
# riga corrente del menu a tendina
ligne=curseur.fetchone()
while ligne:
print ligne
# riga successiva del menu a tendina
ligne=curseur.fetchone()
else:
# non ci sono campi - non era un menu a tendina
print "%s lignes(s) a (ont) ete modifiee(s)" % (curseur.rowcount)
# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
# utilizza la connessione (HOTE,ID,PWD,BASE)
# esegue su questa connessione i comandi SQL contenuti nel file di testo SQL
# questo file è un file di comandi SQL da eseguire al ritmo di uno per riga
# se «seguito=1», allora ogni esecuzione di un comando SQL viene seguita da un messaggio che ne indica il successo o il fallimento
# se «arresto=1», la funzione si interrompe al primo errore riscontrato; in caso contrario, esegue tutti i comandi SQL
# la funzione restituisce un array (numero di errori, errore1, errore2, ...)
# si verifica la presenza del file SQL
data=None
try:
data=open(SQL,"r")
except:
return [1,"Le fichier %s n'existe pas" % (SQL)]
# connessione
try:
connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,erreur:
return [1,"Erreur lors de la connexion a MySQL sous l'identite (%s,%s,%s,%s) : %s" % (HOTE, ID, PWD, BASE, erreur)]
# si richiede un cursore
curseur=connexion.cursor()
# esecuzione delle query SQL contenute nel file SQL
# vengono inserite in un array
requetes=data.readlines()
# le si eseguono una alla volta - inizialmente nessun errore
erreurs=[0]
for i in range(len(requetes)):
# si memorizza la richiesta corrente
requete=requetes[i]
# la query è vuota? Se sì, si passa alla query successiva
if re.match(r"^\s*$",requete):
continue
# esecuzione della richiesta i
erreur=""
try:
curseur.execute(requete)
except Exception, erreur:
pass
#si è verificato un errore?
if erreur:
# Un altro errore
erreurs[0]+=1
# messaggio di errore
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# monitoraggio dello schermo o no?
if suivi:
print msg
# ci fermiamo?
if arret:
return erreurs
else:
if suivi:
print "%s : Execution reussie" % (requete)
# informazioni sul risultato della richiesta eseguita
afficherInfos(curseur)
# Chiusura della connessione e liberazione delle risorse
curseur.close()
connexion.commit()
# si disconnette
try:
connexion.close()
except MySQLdb.OperationalError,erreur:
# un altro errore
erreurs[0]+=1
# messaggio di errore
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# ritorno
return erreurs
# ---------------------------------------------- main
# connessione al database MySQL
# identità dell'utente
ID="admpersonnes"
PWD="nobody"
# il computer host del SGBD
HOTE="localhost"
# identificativo del database
BASE="dbpersonnes"
# identificativo del file di testo contenente i comandi SQL da eseguire
TEXTE="sql2.txt"
# creazione e compilazione della tabella
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
#visualizzazione del numero di errori
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
print erreurs[i]
Note:
- la novità è la riga 100 dello script: dopo l’esecuzione di un comando SQL, vengono richieste informazioni sul cursore utilizzato da questa richiesta. Queste informazioni sono fornite dalla funzione afficheInfos alle righe 16-40;
- righe 19 e 39: se la query SQL eseguita fosse stata una SELECT, l'attributo [curseur.description] sarebbe un array il cui elemento n. i descrive il campo n. i del risultato della query SELECT. Altrimenti, l’attributo [curseur.rowcount] (riga 39) è il numero di righe modificate dalla query INSERT, UPDATE o DELETE;
- righe 32 e 36: il metodo [curseur.fetchone] consente di recuperare la riga corrente da SELECT. Esiste un metodo [curseur.fetchall] che permette di recuperarle tutte in una volta.
Il file delle query eseguite:
Risultati sullo schermo:
Verifica PhpMyadmin:
![]() |











