Saltar al contenido principal

Relaciones uno a muchos en SQLAlchemy

· 6 min de lectura
Héctor Mansilla Arias

Debo reconocer que escribir estas líneas debe ser el desafío más grande que he tenido en años. Si varios años, cuando estaba en 3ro. Medio en 1997 y estudiaba «Programación de Computadores Personales» en el Liceo (uno con letra y números, del cual me siento orgulloso de haber sido estudiante), un tremendo profesional, amigo y mejor ser humano… Lincoyán Palma, Quien me enseñó el mundo de las Bases de Datos Relacionales… ¿Qué era eso? ¿Dónde están los archivos planos y los índices? ¿Dónde está la programación estructurada y todo lo aprendido en el Liceo? ¿Cómo comprender todo esto si lo único que se de Bases de Datos es COBOL, Clipper, Clipper, DBase III Plus y Delphi con archivos planos?

Lincoyán Palma. Experto en Bases de Datos Relacionales y OpenSUSE Ambassador

Fueron meses estudiando… SELECT FROM WHERE JOIN INSERT INTOSQL era toda una locura para alguien como yo que estaba acostumbrado a ver archivos planos como el único tipo de almacenamiento de datos que manejaba… ¿Será por eso que me caen tan bien los Dataset Secuenciales? jajajaja

Pasaron los años y aprendí SQL usándolo en cada proyecto o nuevo desafío que tenía, pero algo pasó y la motivación por desarrollar se fue consumiendo como una batería cuya carga estaba al mínimo. No tenía ganas de seguir desarrollando y fue así como comencé a explorar otras áreas de la Informática… Pero eso es otra historia.

Luego de años sin desarrollar más que «el mínimo indispensable» para adjudicarme proyectos o generar nuevos negocios para las empresas en las que trabajé, durante el Flisol 2010 realizado en la USACH (uno de los mejores realizados hasta hoy en Santiago), asistí a un taller llamado «Revolución Rails». Un nombre bastante llamativo para mi, que no tenía idea de que era eso de Rails y venía del mundo de PHP y su afamada forma poco prolija de escribir código. Fue muy interesante, increíblemente las 3,5 horas se hicieron poco y otras ves no pudimos apreciar en toda su magnitud el Franmework Spring ROO, el cual mostraba cómo a través del lenguaje de programación Groovy.

Rodrigo Salinas – Charla «Revolución Rails» – FLISol 2010, USACH

Recuerdo que ese día algo pasó por mi cabeza y dije «Quizás sea momento de darle otra oportunidad al desarrollo de aplicaciones«.

Desde aquel día, leí muchos manuales, encontré a muchos maestros, algunos cumplieron su misión y siguieron sus respectivos caminos y otros, siguen en contacto y con una gran amistad… Algunos de ellos a kilometros de distancia porque sus locuras son inimaginables!

El segundo evento importante en este largo proceso de 10 años fue hace 5, justo en la mitad del camino asistí a una charla que sin querer marcó un antes y un después… El responsable de esta charla, el gran Felipe Cabargas, alias @juanpintoduran en Twitter.

Felipe Cabargas – @juanpintoduran

Gracias a mi gran amigo, conocí Ruby y Rails… Y fue tanta la comodidad de trabajar con el lenguaje, lo simple del aprendizaje y lo robusto que era para generar prototipos de proyectos rápidamente, que lo comencé a utilizar en todas las «cosas pequeñas» que requería día a día.

El gran problema fue, sin importar el Framework ni el Lenguaje detrás de él, comprender cómo el ORM en el modelo de datos, maneja las relaciones entre tablas de la Base de Datos.

El sólo hecho de entender el patrón de diseño «Modelo, Vista, Controlador» me tomó años… Claro, para un dinosaurio cuyo único acercamiento a desarrollo web fue con ASP y PHP, que me hablen de ORM y Modelos de Datos, Vistas y Controladores (Rutas, etc.) era Too Much!

El tercer impacto (Al más puro estilo Neon Genesis Evangelion), fue hace un par de años, cuando mi señora me llevó de sorpresa al Museo Ferroviario, ese día estaba con un tremendo enredo para tratar de aplicar algo tan simple como una relación Uno A Muchos en el ORM ActiveRecord y no entendía cómo hacerla.

Ese día, sentado frente a uno de los trenes, algo pasó y casi como un milagro comprendí todo… Como que todas las horas de videos, tutoriales, manuales leídos y charlas asistidas cobraron sentido.

Desde ese momento hasta ahora, sólo había hecho cosas para aprender, nada importante… Hasta ahora.

Fue un después del estallido social, donde me consultan respecto a como estamos para enfrentar un nuevo desafío… Otra vez tengo que desarrollar, pero esta vez no estoy solo, Hay todo un equipo que esta en la misma para que el proyecto salga adelante. A ellos, mi gratitud y reconocimiento.

Equipo Delta – Contingencia por Estallido Social 2019

…Y esta historia aún no termina, seguiré escribiendo entradas respecto a cosas que vaya aprendiendo y necesite recordar pero este es el momento de agradecer a todos por estar presentes.

Bueno, a lo que vinimos!

Entendiendo cómo se establece la relación Uno a Muchos en ORM (En este caso, en SQLAlchemy)

Reproduciremos el clásico ejemplo de Department/Employee obtenido de pythoncentral.

Empezamos definiendo ambos modelos. Employee tiene una ForeignKey a Department llamado departmentid. Hasta aquí todo normal, pero seguidamente se define una relationship llamada department que apunta al modelo Department. Con este simple hecho, ya podemos acceder al departamento del empleado ya que el ORM construye y ejecuta automáticamente la consulta en el momento en que se accede a la instancia del objeto Employee. Se puede tener control sobre la forma y tiempo de ejecución de esta consulta mediante el parámetro _lazy que puede buscarse en la documentación.

Notar que department lleva también un backref. Se trata de la referencia inversa desde Department a todos sus Employee. Con esta única línea también podremos acceder desde un departamento a todos sus empleados a través de Department.employees.

Los modelos

from sqlalchemy import Column, String, Integer, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Department(Base):
__tablename__ = 'department'
id = Column(Integer, primary_key=True)
name = Column(String)

class Employee(Base):
__tablename__ = 'employee'
id = Column(Integer, primary_key=True)
name = Column(String)
department_id = Column(Integer, ForeignKey('department.id'))
department = relationship(
Department, backref=backref('employees', uselist=True))

En la consola de Python ingresamos algunos datos

s = session()
it_department = Department(name='IT')
s.add(Employee(name='Pepe', department=it_department))
s.add(Employee(name='Joaquin', department=it_department))
s.add(Employee(name='Ramon', department=it_department))
s.add(it_department)
s.commit()

Consultamos todos los empleados de IT, via Department usando el ORM

it = s.query(Department).filter(Department.name == 'IT').one()
print "employees: {}".format(it.employees)
print "empleat zero: {}".format(it.employees[0].name)
print "tots els empleats"
for t in it.employees:
print "{}".format(t.name)

Así, queda fácilmente explicado cómo realizar, utilizar y comprender cómo funcionan las relaciones Uno a Muchos en el ORM SQLAlchemy.

Namasté!