ORM (Object-relational mapping) un poquito de sqlalchemy
En el esquema de la arquitectura de GECO aparece como una parte bastante importante en el demonio "gecod" SQLObject.
Un ORM simplifica el acceso a una base de datos por parte del programador convirtiendo toda sentencia sql a operaciones con objetos. Así por ejemplo añadir una fila a una tabla es tan fácil como crear un objeto.
Después de algún tiempo pensandolo he decidido que sería mejor opción utilizar SQLAlchemy, ¿por qué este cambio? Bueno, son varias razones las que me han llevado finalmente a explorar este nuevo ORM:
- Es más potente que SQLObject
- Ya conocía SQLObject, una oportunidad de conocer otro ORM
He estado mirando un poco la documentación de SQLAlchemy y voy a explicar de forma breve la manera más sencilla de utilizar este ORM en python.
Definición de una tabla/objeto
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, backref, sessionmaker
Base = declarative_base()
metadata = Base.metadata
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(20))
fullname = Column(String(50))
def __init__(self, name, fullname):
self.name = name
self.fullname = fullname
def __repr__(self):
return "
db = create_engine('sqlite:///database.sqlite', echo=False)
metadata.create_all(db)
Así de fácil se declara un simple objeto. Esto se refleja en una base de datos con una tabla, de nombre 'users', con las columnas id, name y fullname.
Con metadata.create_all(db) se crea la tabla en la base de datos (La base de datos puede ser sqlite, mysql, postgresql,...).
Creación de objetos
session = Session()
u = User('dani', 'daniel garcia')
session.save(u)
session.commit()
De esta forma tan simple se pueden crear usuarios que se verán reflejados en la base de datos relacional como una nueva fila en la tabla de usuarios.
Es necesario crear un objeto de tipo session para interactuar con la base de datos.
Y para eliminar una entrada nada más simple que
session.commit()
Consultas
Se pueden hacer multitud de consultas con filter y además se pueden concatenar filters -> filter(User.name == 'dani').filter(User.fullname == 'daniel garcia')....
Relaciones
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
user = relation(User, backref=backref('addresses',
order_by=id, cascade='all, delete-orphan',
passive_deletes=False))
def __init__(self, email_address):
self.email_address = email_address
def __repr__(self):
return "
Si queremos declarar una tabla que esté relacionada con otra se utiliza ForeignKey. Además hay que definir una relación, y backref nos da la referencia en la tabla padre, es decir que la tabla padre tendrá este atributo. Con cascade y passive_deletes se consigue el borrado en cascada, cuando se borre un usuario se borraran todas los emails asociados a este.
print u.addresses
u.addresses.append(Address('dani@danigm.net'))
print u.addresses
session.commit()
session.query(User, Address).filter(User.id == Address.user_id).filter(Address.email_address == 'dani@danigm.net').first()
Con este ejemplo se ve como se pueden hacer consultas sobre la unión de varias tablas.




Comments
Ventajas sobre SQLObject?
Interesante, ya me comentaste algo sobre SQLAlchemy y salvo por las consultas encadenadas filter().filter().filter(), curioso aunque implementable con SQL a pelo, no veo en tus ejemplos ninguna power-feature que no pueda encontrar en SQLObject.
Supongo, claro, que es porque se trata de una introducción muy básica, pero sería interesante que destacaras algunas características originales de SQLAlchemy.
Algunas ventajas frente a
Algunas ventajas frente a SQLObject:
- Soporta bases de datos oracle.
- Tiene soporte de claves compuestas, la clave primaria puede ser más de un campo.
- Una tabla se puede referenciar a si misma.
- Se puede adaptar a cualquier base de datos ya creada.
- Las consultas son más eficientes.
...
Buena introduccion
Me ha venido que ni pintada esta introducción para poder usar una pequeña base de datos para mi proyecto, gracias dani ;)
Saludos!!