SqlSoup, mapeo de bases de datos a python con SqlAlchemy
El otro día un amigo me preguntó como hacer consultas a una base de datos mysql desde python y le comenté que con sqlalchemy se podía hacer. Yo ya había hecho algunas cosas con sqlalchemy, pero no había tratado con bases de datos ya creadas, sino que siempre las creaba con sqlalchemy.
He estado mirando un poco en la web de sqlalchemy y me he encontrado SqlSoup (SqlAlchemy).
SqlSoup mapea una base de datos ya creada a objetos python, así que no es necesario crear las clases o declarar las tablas en código python, se infieren directamente de la base de datos ya creada.
Veamos como funciona con un simple ejemplo con sqlite.
-
Creamos la base de datos sqlite para las pruebas
-
Aquí un script de prueba para ejecutar
-
Veamoslo paso a paso
[c]
$ sqlite3 testdb.sqlite
sqlite> create table users (name varchar(50), email varchar(100), primary key (name));
sqlite> create table posts (id integer not_null auto_increment, user_id varchar(50),
...> text varchar, primary key (id), foreign key (user_id) references users(name));
[/c]
[python]
# http://www.sqlalchemy.org/docs/05/reference/ext/sqlsoup.html
# Mapeando una base de datos ya creada para usar desde python de
# manera simple y rapida.
# creamos la base de datos con sqlite3
# sqlite3 testdb.sqlite
# sqlite> create table users (name varchar(50), email varchar(100), primary key (name));
# sqlite> create table posts (id integer not_null auto_increment, user_id varchar(50),
# ...> text varchar, primary key (id), foreign key (user_id) references users(name));
from sqlalchemy.ext.sqlsoup import SqlSoup, Session
from sqlalchemy import or_, and_, desc
#db = SqlSoup('mysql://scott:tiger@localhost/mydatabase')
db = SqlSoup('sqlite:///testdb.sqlite')
def add_users():
user = db.users.insert(name='danigm', email='dani@exp.com')
user2 = db.users.insert(name='dani', email='danigm@exp.com')
user3 = db.users.insert(name='pepe', email='pepe@exp.com')
user4 = db.users.insert(name='juan', email='juan@exp.com')
db.flush()
Session.commit()
def add_posts():
post1 = db.posts.insert(id=1, user_id='danigm', text='comentario1')
post2 = db.posts.insert(id=2, user_id='danigm', text='comentario2')
post3 = db.posts.insert(id=3, user_id='pepe', text='comentario3')
post4 = db.posts.insert(id=4, user_id='juan', text='comentario4')
db.flush()
Session.commit()
try:
add_users()
except:
Session.rollback()
try:
add_posts()
except:
Session.rollback()
print db.users.filter(db.users.name=='danigm').first().name
where = or_(db.users.name=='danigm',
db.users.email=='danigm@exp.com')
users = db.users.filter(where).order_by(desc(db.users.name)).all()
print users
user = users[0]
for post in db.posts.filter(db.posts.user_id == user.name):
print user.name, post.text
[/python]
[python]
db = SqlSoup('sqlite:///testdb.sqlite')
[/python]
Con esta simple línea tenemos el objeto db que está conectado con la base de datos y ya podemos empezar a hacer consultas u otras cosas.
[python]
user = db.users.insert(name='danigm', email='dani@danigm.net')
db.flush()
Session.commit()
[/python]
Podemos acceder a las tablas por su nombre directamente, db.users, db.posts y estos objetos tienen métodos para insertar, borrar o filtrar de tal forma que podamos hacer la consulta deseada, en este ejemplo añadimos un usuario. Hay que tener en cuenta que para que los cambios se vean reflejados hay que ejecutar el commit().
[python]
print db.users.filter(db.users.name=='danigm').first().name
[/python]
se puede filtrar como en cualquier objeto de sqlite, en este ejemplo filtramos por nombre de usuario, nos quedamos con el primero y mostramos el nombre del mismo.
[python]
where = or_(db.users.name=='danigm',
db.users.email=='danigm@exp.com')
users = db.users.filter(where).order_by(desc(db.users.name)).all()
print users
user = users[0]
for post in db.posts.filter(db.posts.user_id == user.name):
print user.name, post.text
[/python]
Y una vez dominado el uso de sqlalchemy se pueden hacer filtros más complejos con otras directivas. combinando filtros y usando toda la potencia que te da sqlalchemy.
Con este ejemplo vemos que acceder a bases de datos desde python es muy fácil con sqlalchemy y además puedes hacerlo independiente del motor de base de datos gracias a que sqlalchemy soporta mysql, postgresql, sqlite, oracle, firebird, MS-SQL, MSAccess.




Comments
Gracias por este post, me
Gracias por este post, me sera de mucha ayuda! eres un crare
una cosa es que no quieras
una cosa es que no quieras que escriban bots y otra los captchas que pones!! he tenido que escribir 3 para acertar.
He cambiado un poco el capcha
He cambiado un poco el capcha este, los puntitos de colores lo mismo metían mucho ruido :P
Mas pythonico
Creo que puedes mejorar el código un poco más haciéndolo más pythonico y utilizando bucles for a modo de iterador para insertar los usuarios, por ejemplo:
def add_users():
for (name, email) in [('danigm','dani@exp.com'),('dani','danigm@exp.com'),('pepe','pepe@exp.com'),('juan','juan@exp.com'),]
db.users.insert(name, email)
db.flush()
Session.commit()
Lo mismo en otras partes del código ;) Buen ejemplo, me será útil.