9. Uso de SGBD MySQL
![]() |
9.1. Instalación del módulo MySQLdb
Vamos a escribir scripts utilizando una base de datos MySQL:
![]() |
Las funciones de Python para la gestión de una base de datos MySQL están encapsuladas en un módulo MySQLdb que no está incluido en la distribución inicial de Python. Por lo tanto, es necesario descargar e instalar el módulo. A continuación se indica cómo hacerlo:
![]() |
- En el menú de programas, seleccione el gestor de paquetes de Python. Aparecerá la ventana de comandos.
Busque la palabra clave mysql en los paquetes:
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.
Se han listado todos los módulos cuyo nombre o descripción contienen la palabra clave mysql. El que nos interesa es [mysql-python], línea 14. Lo instalamos:
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
- línea 5: el paquete mysql-python-1.2.3 se ha instalado en la carpeta «%APPDATA%\Python», donde APPDATA es la carpeta designada en la línea 8.
Esta operación puede fallar si:
- el intérprete de Python utilizado es un version de 64 bits;
- la ruta %APPDATA% contiene caracteres acentuados.
9.2. Instalación de MySQL
Existen varias formas de instalar SGBD MySQL. Aquí hemos utilizado WampServer, un paquete que incluye varios programas:
- un servidor web Apache. Lo utilizaremos para escribir scripts web en Python;
- el SGBD MySQL;
- el lenguaje de scripting PHP;
- una herramienta de administración de SGBD MySQL escrita en PHP: phpMyAdmin.
WampServer se puede descargar (junio de 2011) en la siguiente dirección:
![]() |
- en [1], se descarga el archivo version de WampServer que sea el adecuado;
- en [2], una vez instalado, lo ejecutamos. Esto iniciará el servidor web Apache y el SGBD MySQL;
- en [3], una vez iniciado, WampServer se puede administrar desde un icono [3] situado en la parte inferior derecha de la barra de tareas;
- en [4], se inicia la herramienta de administración de MySQL.
Se crea una base de datos [dbpersonnes]:

Se crea un usuario [admpersonnes] con la contraseña [nobody]:
![]() | ![]() |
![]() |
- en [1], el nombre del usuario;
- en [2], el equipo de SGBD en el que se le conceden derechos;
- en [3], su contraseña [nobody];
- en [4], lo mismo;
- en [5], no se le otorgan derechos a este usuario;
- en [6], se crea.
![]() |
- en [7], se vuelve a la página de inicio de phpMyAdmin;
- en [8], se utiliza el enlace [Privileges] de esta página para ir a modificar los del usuario [admpersonnes] [9].
![]() |
- en [10], se indica que se desea otorgar al usuario [admpersonnes] derechos sobre la base de datos [dbpersonnes];
- en [11], se valida la selección.
![]() |
- con el enlace [12] [Tout cocher], se conceden al usuario [admpersonnes] todos los derechos sobre la base de datos [dbpersonnes] [13];
- se valida en [14].
Ahora tenemos:
- una base de datos MySQL [dbpersonnes];
- un usuario [admpersonnes / nobody] que tiene todos los derechos sobre esta base de datos.
Vamos a escribir scripts en Python para explotar la base de datos.
9.3. Conexión a una base de datos MySQL - 1
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# conexión a una base de datos MySQL
....
Notas:
- líneas 2-4: los scripts que contienen operaciones con SGBD y MySQL deben importar el módulo MySQLdb. Recordemos que hemos instalado este módulo en la carpeta [%APPDATA%\Python]. La carpeta [%APPDATA%\Python] se explora automáticamente cuando un código Python solicita un módulo. De hecho, se exploran todas las carpetas declaradas en sys.path. A continuación se muestra un ejemplo que muestra estas carpetas:
# -*- coding=utf-8 -*-
import sys
# Visualización de carpetas del sistema.path
for dossier in sys.path:
print dossier
La salida en pantalla es la siguiente:
Línea 8, la carpeta [site-packages] donde se instaló inicialmente MySQLdb. Movemos la carpeta [site-packages], que es la carpeta donde la utilidad pypm instala los módulos de Python. Para añadir una nueva carpeta que Python explorará en busca de módulos, la añadimos a la lista sys.path:
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# conexión a una base de datos MySQL
....
En la línea 3, añadimos la carpeta a la que se ha movido el módulo MySQLdb.
El código completo del ejemplo es el siguiente:
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# conexión a una base de datos MySQL
# la identidad del usuario es (admpersonnes,nobody)
user="admpersonnes"
pwd="nobody"
host="localhost"
connexion=None
try:
print "connexion..."
# conexión
connexion=MySQLdb.connect(host=host,user=user,passwd=pwd)
# seguimiento
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
- líneas 8-11: el script conectará (línea 15) al usuario [admpersonnes / nobody] al SGBD MySQL de la máquina [localhost]. No se conecta a una base de datos concreta;
- líneas 12-24: la conexión puede fallar. Por eso se realiza en un try / except / finally;
- línea 15: el método connect del módulo MySQLdb admite diferentes parámetros denominados:
- user: usuario propietario de la conexión [admpersonnes];
- pwd: contraseña del usuario [nobody];
- host: máquina del SGBD MySQL [localhost];
- db: la base de datos a la que se conecta. Opcional.
- línea 18: si se lanza una excepción, será de tipo [ MySQLdb.OperationalError] y el mensaje de error asociado se encontrará en la variable [message] ;
- líneas 20-23: en la cláusula [finally], se cierra la conexión. En caso de excepción, se intercepta (línea 23), pero no se realiza ninguna acción al respecto (línea 24).
connexion...
Connexion a MySQL reussie sous l'identite host=localhost,user=admpersonnes,passwd=nobody
9.4. Conexión a una base de datos MySQL - 2
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# ---------------------------------------------------------------------------------
def testeConnexion(hote,login,pwd):
# conecta y luego desconecta (login,pwd) del SGBD mysql del servidor host
# lanza la excepción MySQLdb.operationalError
# conexión
connexion=MySQLdb.connect(host=hote,user=login,passwd=pwd)
print "Connexion a MySQL reussie sous l'identite (%s,%s,%s)" % (hote,login,passwd)
# se cierra la conexión
connexion.close()
print "Fermeture connexion MySQL reussie\n"
# ---------------------------------------------- main
# conexión a la base MySQL
# identidad del usuario
user="admpersonnes"
passwd="nobody"
host="localhost"
# prueba de conexión
try:
testeConnexion(host,user,passwd)
except MySQLdb.OperationalError,message:
print message
# con un usuario inexistente
try:
testeConnexion(host,"xx","xx")
except MySQLdb.OperationalError,message:
print message
Notas:
- líneas 7-15: una función que intenta conectar y luego desconectar a un usuario de un SGBD MySQL. Muestra el resultado;
- líneas 18-34: programa principal: llama dos veces al método testeConnexion y muestra las posibles excepciones.
9.5. Creación de una tabla MySQL
Ahora que sabemos cómo crear una conexión con un SGBD MySQL, comenzamos a emitir órdenes SQL en esta conexión. Para ello, nos conectaremos a la base de datos creada [dbpersonnes] y utilizaremos la conexión para crear una tabla en la base de datos.
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# ---------------------------------------------------------------------------------
def executeSQL(connexion,update):
# ejecuta una consulta de actualización en la conexión
# se solicita un cursor
curseur=connexion.cursor()
# ejecuta la consulta sql en la conexión
try:
curseur.execute(update)
connexion.commit()
except Exception, erreur:
connexion.rollback()
raise
finally:
curseur.close()
# ---------------------------------------------- main
# conexión a la base de datos MySQL
# la identidad del usuario
ID="admpersonnes"
PWD="nobody"
# el servidor del SGBD
HOTE="localhost"
# identidad de la base
BASE="dbpersonnes"
# conexión
try:
connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,message:
print message
sys.exit()
# eliminación de la tabla personas si existe
# si no existe, se producirá un error
# se ignora
requete="drop table personnes"
try:
executeSQL(connexion,requete)
except:
pass
# creación de la tabla personas
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()
# se cierra la sesión y se sale
try:
connexion.close()
except MySQLdb.OperationalError,message:
print message
sys.exit()
Notas:
- línea 7: la función executeSQL ejecuta una consulta SQL en una conexión abierta;
- línea 10: las operaciones SQL sobre la conexión se realizan a través de un objeto específico denominado cursor;
- línea 10: obtención de un cursor;
- línea 13: ejecución de la consulta SQL;
- línea 14: se valida la transacción actual;
- línea 15: en caso de excepción, el mensaje de error se almacena en la variable error;
- línea 16: se invalida la transacción actual;
- línea 17: se vuelve a lanzar la excepción;
- línea 19: haya o no error, se cierra el cursor. Esto libera los recursos asociados a él.
create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom)) : requete reussie
Verificación con phpMyAdmin:
![]() |
- la base de datos [dbpersonnes] [1] tiene una tabla [personnes] [2] que tiene la estructura [3] y la clave primaria [4].
9.6. Relleno de la tabla [personnes]
Tras haber creado anteriormente la tabla [personnes], ahora la rellenamos.
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# otros módulos
import re
# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
# utiliza la conexión (HOTE,ID,PWD,BASE)
# ejecuta en esta conexión los comandos SQL contenidos en el archivo de texto SQL
# este archivo es un archivo de comandos SQL que se ejecutarán a razón de uno por línea
# si seguimiento=True, cada ejecución de un comando SQL se muestra en pantalla indicando si ha tenido éxito o ha fallado
# si arret=True, la función se detiene ante el primer error encontrado; de lo contrario, ejecuta todos los comandos sql
# la función devuelve una lista (número de errores, error1, error2, ...)
# se comprueba la presencia del archivo SQL
data=None
try:
data=open(SQL,"r")
except:
return [1,"Le fichier %s n'existe pas" % (SQL)]
# conexión
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)]
# se solicita un cursor
curseur=connexion.cursor()
# ejecución de las consultas SQL contenidas en el archivo SQL
# se colocan en una tabla
requetes=data.readlines()
# se ejecutan una a una; al principio no hay errores
erreurs=[0]
for i in range(len(requetes)):
# se guarda la consulta actual
requete=requetes[i]
# ¿Tenemos una consulta vacía? Si es así, pasamos a la siguiente consulta
if re.match(r"^\s*$",requete):
continue
# ejecución de la consulta i
erreur=""
try:
curseur.execute(requete)
except Exception, erreur:
pass
#¿Ha habido algún error?
if erreur:
# otro error
erreurs[0]+=1
# mensaje de error
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# ¿Seguimiento en pantalla o no?
if suivi:
print msg
# ¿Nos detenemos?
if arret:
return erreurs
else:
if suivi:
print "%s : Execution reussie" % (requete)
# cierre de la conexión y liberación de recursos
curseur.close()
connexion.commit()
# se desconecta
try:
connexion.close()
except MySQLdb.OperationalError,erreur:
# otro error más
erreurs[0]+=1
# mensaje de error
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# volver
return erreurs
# ---------------------------------------------- main
# conexión a la base MySQL
# identidad del usuario
ID="admpersonnes"
PWD="nobody"
# la máquina host del SGBD
HOTE="localhost"
# identidad de la base
BASE="dbpersonnes"
# identidad del archivo de texto de comandos SQL a ejecutar
TEXTE="sql.txt";
# creación y rellenado de la tabla
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
#visualización del número de errores
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
print erreurs[i]
El archivo sql.txt:
Se ha insertado un error a propósito en la línea 5.
Resultados en pantalla:
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"))
Verificación con phpMyAdmin:

- en [1], el enlace [Afficher] permite obtener el contenido de la tabla [personnes] [2].
9.7. Ejecución de consultas SQL cualquiera
El siguiente script permite ejecutar un archivo de comandos SQL y mostrar el resultado de cada uno de ellos:
- el resultado de SELECT si la orden es SELECT;
- el número de líneas modificadas si el comando es INSERT, UPDATE, DELETE.
# importación del módulo MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
# otros módulos
import re
def cutNewLineChar(ligne):
# se elimina el marcador de fin de línea de [ligne] si existe
l=len(ligne)
while(ligne[l-1]=="\n" or ligne[l-1]=="\r"):
l-=1
return(ligne[0:l])
# ---------------------------------------------------------------------------------
def afficherInfos(curseur):
# muestra el resultado de una consulta sql
# ¿Se trataba de una selección?
if curseur.description:
# hay una descripción, por lo que es una selección
# descripción[i] es la descripción de la columna n.º i de la selección
# descripciónQZXW2HTMLBW2ldZQXQZXW2HTMLBWzBdZQX es el nombre de la columna n.º i del select
# se muestran los nombres de los campos
titre=""
for i in range(len(curseur.description)):
titre+=curseur.description[i][0]+","
# se muestra la lista de campos sin la coma final
print titre[0:len(titre)-1]
# línea separadora
print "-"*(len(titre)-1)
# línea actual del select
ligne=curseur.fetchone()
while ligne:
print ligne
# línea siguiente del select
ligne=curseur.fetchone()
else:
# no hay campos: no era un select
print "%s lignes(s) a (ont) ete modifiee(s)" % (curseur.rowcount)
# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
# utiliza la conexión (HOTE,ID,PWD,BASE)
# ejecuta en esta conexión los comandos SQL contenidos en el archivo de texto SQL
# este archivo es un archivo de comandos SQL que se ejecutarán a razón de uno por línea
# si seguimiento=1, cada ejecución de un comando SQL se muestra en pantalla indicando si ha tenido éxito o ha fallado
# si arret=1, la función se detiene ante el primer error encontrado; de lo contrario, ejecuta todos los comandos sql
# la función devuelve una matriz (número de errores, error1, error2, ...)
# se comprueba la presencia del archivo SQL
data=None
try:
data=open(SQL,"r")
except:
return [1,"Le fichier %s n'existe pas" % (SQL)]
# conexión
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)]
# se solicita un cursor
curseur=connexion.cursor()
# ejecución de las consultas SQL contenidas en el archivo SQL
# se colocan en una tabla
requetes=data.readlines()
# se ejecutan una a una; al principio no hay errores
erreurs=[0]
for i in range(len(requetes)):
# se almacena la consulta actual
requete=requetes[i]
# ¿Tenemos una consulta vacía? Si es así, pasamos a la siguiente consulta
if re.match(r"^\s*$",requete):
continue
# ejecución de la consulta i
erreur=""
try:
curseur.execute(requete)
except Exception, erreur:
pass
#¿Ha habido algún error?
if erreur:
# otro error
erreurs[0]+=1
# mensaje de error
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# ¿Seguimiento en pantalla o no?
if suivi:
print msg
# ¿se detiene?
if arret:
return erreurs
else:
if suivi:
print "%s : Execution reussie" % (requete)
# información sobre el resultado de la consulta ejecutada
afficherInfos(curseur)
# cierre de la conexión y liberación de recursos
curseur.close()
connexion.commit()
# nos desconectamos
try:
connexion.close()
except MySQLdb.OperationalError,erreur:
# otro error
erreurs[0]+=1
# mensaje de error
msg="%s : Erreur (%s)" % (requete,erreur)
erreurs.append(msg)
# volver
return erreurs
# ---------------------------------------------- main
# conexión a la base MySQL
# identidad del usuario
ID="admpersonnes"
PWD="nobody"
# la máquina host del SGBD
HOTE="localhost"
# identidad de la base
BASE="dbpersonnes"
# identidad del archivo de texto de comandos SQL a ejecutar
TEXTE="sql2.txt"
# creación y rellenado de la tabla
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
#visualización del número de errores
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
print erreurs[i]
Notas:
- la novedad se encuentra en la línea 100 del script: tras la ejecución de una orden SQL, se solicita información sobre el cursor utilizado por esta consulta. Esta información la proporciona la función afficheInfos de las líneas 16-40;
- líneas 19 y 39: si la consulta SQL ejecutada fuera una SELECT, el atributo [curseur.description] es una matriz cuyo elemento n.º i describe el campo n.º i del resultado de la SELECT. De lo contrario, el atributo [curseur.rowcount] (línea 39) es el número de líneas modificadas por la consulta INSERT, UPDATE o DELETE;
- líneas 32 y 36: el método [curseur.fetchone] permite recuperar la línea actual de SELECT. Existe un método [curseur.fetchall] que permite recuperarlas todas de una sola vez.
El archivo de las consultas ejecutadas:
Resultados en pantalla:
Verificación PhpMyadmin:
![]() |











