Post on 14-Feb-2017
Pycones 2015
Python Comparing ORM
José manuel ortega |@jmortegac
Pycones 2015
https://speakerdeck.com/jmortega
https://medium.com/@jmortegac
Pycones 2015
• Introducción a ORM
• ORM en Python • SqlAlchemy/SQLObject/PonyORM/Peewee/Django-ORM
• Comparativa
• Seguridad
Agenda
Pycones 2015
Introducción a ORM
• Object Relational Mapping
• Mapear objetos en tablas • Crea una BD orientada a objetos virtual
• Es necesario saber cómo funcionan las base de datos a nivel relacional
Pycones 2015
Introducción a ORM
• Mapeo:
• ClaseTabla
• AtributoColumna
• ObjetoFila
Pycones 2015
Ventajas
• Evitar escribir código SQL
• Independizar la fuente de datos
• Mismo código puedo cambiar base de datos
• Fácil modelado de datos
Pycones 2015
Patrones ORM
• Unit of Work
Pycones 2015
Patrones ORM
• Identity Map
• Caché de objetos
Objetos en
BD
Objetos en memoria
Pycones 2015
Introducción a ORM
• Patrones:
• Active Record Pattern
• Relacion 1:1
Object Table /row
Pycones 2015
Introducción a ORM
• Patrones:
• Data Mapper Pattern
Object DataMaper Database
Pycones 2015
ORM en python
SELECT * FROM USERS WHERE zip_code=94107;
users = Users.objects.filter(zip_code=94107)
Pycones 2015
Soporte Bases datos
Pycones 2015
Soporte web FrameWorks
Pycones 2015
Modelo de datos
Pycones 2015
SQLiteBrowser
Pycones 2015
SQLiteBrowser
Pycones 2015
Muchos a muchos
Pycones 2015
SQLalchemy
• Es de los más avanzados • Más flexible para el programador
• Patrón unit of Work
Pycones 2015
SQLalchemy
• Objeto session para persistir los objetos
• session.commit()
Pycones 2015
SQLalchemy Many to many
Pycones 2015
SQLalchemy
Query objects
Pycones 2015
SQLObject
http://sqlobject.org
• No es necesario commit
• Soporta joins
• Relaciones uno-muchos, muchos-muchos
Pycones 2015
SQLObject
event = Event(type="workshop",
description="Usando contenedores para Big Data",
date=date1,
track = track4);
event.addSpeaker(speaker1);
class Event(SQLObject): type = StringCol(length=255) #workshop /talk description = StringCol(length=255) date = DateCol(default=None) track = ForeignKey('Track') speakers = RelatedJoin('Speaker', intermediateTable="speaker_event", joinColumn="eventID", otherColumn="speakerID")
Pycones 2015
SQLObject
<Nombre_clase>.connection.debug=True
Pycones 2015
SQLObject Many to Many
Pycones 2015
Expresiones SQL
SQLObject
event = Event.select(Event.q.description==description)
Pycones 2015
SQLBuilder
from sqlobject.sqlbuilder import *
Pycones 2015
Generación dinámica
A partir de un xml o esquema
Pycones 2015
PonyORM
• Funciona de forma similar a SQLalchemy,mejorando algunas cosas
• Puede trabajar a la vez con varias BD
• Relaciones bidireccionales
https://ponyorm.com
Pycones 2015
PonyORM
db_session
• Realiza un commit si detecta cualquier cambio y no se ha producido ninguna excepción
• Realiza un rollback de la transacción si se produce una excepción
• Gestiona el pool de conexiones con la BD
• Gestiona caché de sesión de forma automática
Pycones 2015
PonyORM
db_session decorator
Pycones 2015
PonyORM
Lambda function
Pycones 2015
PonyORM
Many to Many
Pycones 2015
PonyORM ventajas • Optimización automática de consultas(Automatic
query optimization)
• Gestión automática de transacciones
• Almacenamiento en caché automático de consultas y objetos
• Soporte completo de claves primarias compuestas
• La capacidad de escribir con facilidad consultas utilizando LEFT JOIN, VISTA y otras características de SQL
Pycones 2015
Django ORM
Pycones 2015
Peewee
https://github.com/coleifer/peewee
• Definición de modelos similar a Django
• Patrón ActiveRecord
Pycones 2015
Soporte python 3
SQLObject
Pycones 2015
Primary key
• All create it automatically except SQLAlchemy
id = Column(Integer, primary_key=True)
Pycones 2015
Autocommit=true
db_session
SQLObject
Pycones 2015
Transacciones
try:
with db.atomic() as nested_txn:
object = Entity.create()
return 'Success'
except peewee.IntegrityError:
# This will roll back the above create() query.
nested_txn.rollback()
return 'Failure'
Pycones 2015
Transacciones
@db.atomic() def create_entity():
# This statement will run in a transaction. If the caller is already
# running in an `atomic` block, then a savepoint will be used instead.
return Entity.create()
Pycones 2015
Performance
# Faster
with db.atomic():
for data_dict in data_source:
Model.create(**data_dict)
# Fastest
with db.atomic():
Model.insert_many(data_source).execute()
Pycones 2015
Cache
• Minimizar número de llamadas a BD
• Optimizar consultas
• Identity Map
object = Entity[primary_key]
obj = Entity.objects.get(pk=the_id)]
Pycones 2015
Get Data from Caché
object = Entity.get(Entity.pk == 'value')
object = session.query(Entity).get(pk='value')
Pycones 2015
Generating tables
• PeeWee
db.create_tables([Entity1,Entity2,...,Entityn],True)
try:
<Entity>.create_table()
except peewee.OperationalError:
print “Table already exists!”
Pycones 2015
Generating tables
SQLObject
Base.metadata.create_all(engine)
for each Entity:
Entity.createTable(ifNotExists=True)
Pycones 2015
Generating tables
db = Database("sqlite", "ponyORM_pycon.sqlite", create_db=True)
class Entity(db.Entity):
db.generate_mapping(create_tables=True)
Pycones 2015
Herencia
• Todas soportan herencia para crear las entidades
Pycones 2015
Herencia
Pycones 2015
Herencia
Pycones 2015
Comparativa SQLAlchemy SQLObject PonyORM Peewee Django ORM
Soporte sesión en Base de datos
Automatic Schema Migrations
Many-to-many relations intuitive
Automatic query optimization
Unit of Work
Pycones 2015
Soporte BD ORM BD
SQLAlchemy
MySQL, Postgres, SQLite, Oracle, MSSQLServer,Sybase,FireBird
SQLObject
MySQL, Postgres, SQLite, Sybase, Maxdb, MSSQLServer
PonyORM
MySQL, Postgres, SQLite, Oracle
Peewee
MySQL, Postgres, SQLite
Django ORM
MySQL, Postgres, SQLite,Oracle
Pycones 2015
Seguridad
query = MyModel.select().where(SQL('Some SQL expression %s' % user_data))
query = MyModel.select().where(SQL('Some SQL expression %s' , user_data))
Pycones 2015
Django security
• Binding parameters
Pycones 2015
GitHub examples
https://github.com/jmortega/pycon-comparing_ORM
Pycones 2015
Testing examples
http://code.runnable.com/Vk8C1Vkf2dAQGrrc/python-comparing-orm-for-sqlobject-sqlalchemy-ponyorm-and-peewee
http://bit.ly/1O9gDn5
Pycones 2015
Thank you!
?