Está en la página 1de 7

Página 1 de 7

Acceso A Bases De Datos Desde


Python: Interfaz Db-Api
Contents

 ¿Cómo me conecto a una base de datos con MySQL?


 ¿Cómo me conecto a una base de datos con PostgreSQL?

 Parámetros

En python, el acceso a bases de datos esta estandarizado por la


especificación Database API (DB-API), actualmente en la versión
2.0 (PEP 249: Python Database API Specification v2.0)

Gracias a esto, se puede acceder a cualquier base de datos


utlizando la misma interfaz (ya sea un motor remoto, local, ODBC,
etc.). Se puede comparar con DAO, ADO, ADO.NET en el mundo
Microsoft, o a JDBC en el mundo Java.

O sea, el mismo codigo se podría llegar a usar para cualquier base


de datos, tomando siempre los recaudos necesarios (lenguaje SQL
estándard, estilo de parametros soportado, etc.)

Por ello, el manejo de bases de datos en python siempre sigue


estos pasos:

1. Importar el conector
2. Conectarse a la base de datos (función connect del módulo
conector)
3. Abrir un Cursor (método cursor de la conexión)
4. Ejecutar una consulta (método execute del cursor)
5. Obtener los datos (método fetch o iterar sobre el cursor)
Página 2 de 7
6. Cerrar el cursor (método close del cursor)

¿Cómo me conecto a una base de


datos con MySQL?
Este es un ejemplo basico de como hacerlo con MySQL:

>>> import MySQLdb


>>> db = MySQLdb.connect(host="localhost",
user="root",
... passwd="mypassword", db="PythonU")
Una vez establecida la conexion, hay que crear un "cursor". Un
cursor es una estructura de control que se usa para recorrer (y
eventualmente procesar) los records de un result set.

El metodo para crear el cursor se llama, originalmente, cursor():

>>> cursor = db.cursor()


Ya tenemos la conexion establecida y el cursor creado, es hora de
ejecutar algunos comandos SQL:

>>> cursor.execute("SELECT * FROM Students")


5L
El metodo execute se usa para ejecutar comandos SQL. Note que
no hace falta agregar el ';' (punto y coma) al final del comando.
Ahora es cuestion de recorrer el objeto cursor.

Para obtener un solo elemento, usamos fetchone():

>>> cursor.fetchone()
Página 3 de 7
(1L, 'Joe', 'Campbell', datetime.date(2006,
2, 10), 'N')

>>> cursor.fetchall()
((1L, 'Joe', 'Campbell', datetime.date(2006,
2, 10), 'N'),
(2L, 'Joe', 'Doe', datetime.date(2004, 2,
16), 'N'),
(3L, 'Rick', 'Hunter', datetime.date(2005, 3,
20), 'N'),
(4L, 'Laura', 'Ingalls', datetime.date(2001,
3, 15), 'Y'),
(5L, 'Virginia', 'Gonzalez',
datetime.date(2003, 4, 2), 'N'))
Cual metodo usar dependera de la cantidad de datos que
tengamos, la memoria disponible en la PC y sobre todo, de como
querramos hacerlo. Si estamos trabajando con datasets limitados,
no habra problema con el uso de fetchall(), pero si la base de datos
es lo suficientemente grande como para entrar en memoria, se
podria implementar una estrategia como la que se encuentra aca:

import MySQLdb
db = MySQLdb.connect(host="localhost",
user="root",passwd="secret", db="PythonU")
cursor = db.cursor()
recs=cursor.execute("SELECT * FROM Students")
for x in range(recs):
print cursor.fetchone()
O directamente:

import MySQLdb
Página 4 de 7
db = MySQLdb.connect(host="localhost",
user="root",passwd="secret", db="PythonU")
cursor = db.cursor()
cursor.execute("SELECT * FROM Students")
for row in cursor:
print row
(Sebastian Bassi)

¿Cómo me conecto a una base de


datos con PostgreSQL?
Otro ejemplo basico de como hacerlo con PostgreSQL (similar al
de MySQL). Se usó el esquema: CREATE TABLE estudiante (
nombre varchar,  apellido varchar,  fecha date, 
booleano bool,  legajo serial PRIMARY KEY); Antes
que nada se debe instalar el conector (para unix y windows).

Primero importar el conector y crear la conexión a la base de datos:

>>> import psycopg2, psycopg2.extras


>>> conn =
psycopg2.connect(database='test',user='postgr
es',password='pass', host='localhost')
Luego crear un cursor para obtener los datos y ejecutar consulta:

>>> cur = conn.cursor()


>>> cur.execute("SELECT * FROM estudiante")
>>> rows=cur.fetchall()
>>> print rows
Página 5 de 7

[['Joe', 'Capbell', datetime.date(2006, 2,


10), False, 1], ['Joe', 'Doe',
datetime.date(2004, 2, 16), False, 2],
['Rick', 'Hunter', datetime.date(2005, 3,
20), False, 3], ['Laura', 'Ingalls',
datetime.date(2001, 3, 15), True, 4],
['Virginia', 'Gonzalez', datetime.date(2003,
4, 2), False, 5]]
Algo más pitónico es crear el cursor simil diccionario (en vez de
una lista de valores):

>>> cur =
conn.cursor(cursor_factory=psycopg2.extras.Di
ctCursor)
>>> cur.execute("SELECT * FROM estudiante")
>>> for row in cur: # itero sober cada fila
>>> # row es un diccionario, con las
claves = nombres de campos
>>> print "Nombre y Apellido: %s, %s " %
(row['nombre'],row['apellido'])

Nombre y Apellido: Joe, Capbell


Nombre y Apellido: Joe, Doe
Nombre y Apellido: Rick, Hunter
Nombre y Apellido: Laura, Ingalls
Nombre y Apellido: Virginia, Gonzalez
Nota: esto es propio del conector psycopg2. Igualmente otros
conectores tambien lo soportan o se puede imitar (leyendo el
atributo description del cursor que tiene la información de los
campos):
Página 6 de 7
>>> print cur.description
(('nombre', 1043, 8, -1, None, None, None),
('apellido', 1043, 8, -1, None, None, None),
('fecha', 1082, 10, 4, None, None, None),
('booleano', 16, 1, 1, None, None, None),
('legajo', 23, 1, 4, None, None, None))

Parámetros
Pregunta: Hola chicos. Estoy con un inconveniente que no puedo
solventar. Tengo una funcion de python que genera unos
querystrings para postgres.

Mi problema empieza cuando, por ejemplo hay uno de esos


apellidos que tienen ', Ej: D'agostino

como resultado me queda el string (ejemplo)

'insert into personas (apellido) values


("D'agostino")'
Respuesta:

Lo que tendrías que hacer es que postgres te escapee


automaticamente los valores, usando los parámetros de db-api
(segúndo argumento del metodo execute del cursor):

cur = conn.cursor()
cur.execute("insert into personas (apellido)
values (%s)" , ["D'agostino"])
Página 7 de 7
Así, automáticamente postgres sabe, según el tipo de datos del
parámetro, en este caso un string = "D'agostino", como escapear y
formatear el sql para que no de error.

Además, esto es mas seguro frente a ataques por "inyección de


sql", porque el formateo es automático, en vez de usar
directamente el operador % sobre el query y pasarselo cocinado a
la base.

Para hacerlo más robusto, podrías usar diccionario con los


parametros (es más seguro en el caso que tengas varios
parámetros, para evitar errores):

cur.execute("insert into personas (apellido)


values (%(apellido)s)" ,
{"apellido":"D'agostino"})
Igualmente, esto dependerá de las capacidades de cada conector
(consultar variable paramstyle del módulo conector), pudiendo
utilizarse los siguientes estilos de parametros:

 'qmark': Signo de interrogación, ej. '...WHERE name=?'


 'numeric': Numerico, posicional, ej. '...WHERE name=:1'
 'named': por Nombre, ej. '...WHERE name=:name'
 'format': Formato ANSI C, ej. '...WHERE name=%s'
 'pyformat': Formato Python, ej. '...WHERE name=%(name)s'

También podría gustarte