SQLObject: Relaciones one-to-one y one-to-many

Noviembre 20, 2007

Quiero contarles mas o menos de que se trata este tema, hoy estuve es estudiando el Modelo de Entidad Relacion de Ghhp, aplicacion que estamos desarrollando con unos amigos y note que había algunas cosas que no me quedaban del todo claro, es decir, de cómo iba a implementar eso en SQLObject, que es el ORM(Object Relational Manager)que optamos usar.
En particular qué hacer con los atributos de las relaciones y cómo afrontar las relaciones binarias con multiplicidad 1..n y las relaciones trinarias.

Soluciones (ó intento de…) a los cuestionamientos anteriores:

Atributos de las relaciones:
Free Image Hosting at www.ImageShack.us
En el Modelo Relacional, las relaciones al igual que las entidades, pueden poseer atributos. Por ejemplo: para registrar el numero de horas por semana que un empleado trabaja en un proyecto, podemos incluir un atributo hora a la relacion TRABAJA_EN. Hasta ahora todo bien, pero cuando queremos crear las clases para contener esas entidades y la relación, ¿a dónde va a para ese atributo?. Eso depende de la multiplicidad de la relacion con las entidades, si tenemos 1:1 ó 1:n, lo podremos trasladar a uno de los tipos de entidad participante.

  1. 1:1 Lo podemos trasladar a cuelquier entidad a la hora de crear las clases sqlobject
  2. 1:n Solo lo podremos trasladar al tipo de entidad que esta del lado n de la relacón.

Relaciones binarias con multiplicidad 1..n (one-to-many)
Para esto lo que nos provee SQLObject es MultipleJoin. ¿Qué es esto?, simplemente significa que un objeto de la clase del tipo A esta contenido por multiples objetos del tipo B. Por ejemplo:un módulo de python contiene múltiples funciones, pero las funciones solo pertenecen a un solo módulo.
Representemos este concepto en SQLObjet:

>>> class PythonFunction(SQLObject):

...     name = StringCol()

...     modulo_id = ForeignKey('PythonModule')

...

>>> class PythonModule(SQLObject):

...     name = StringCol()

...     functions = MultipleJoin('PythonFunction',

                          joinColumn='module_id')

...

>>> PythonFunction.createTable()

>>> PythonModule.createTable()

>>>

Agregemos objetos

>>> modulo = PythonModule(name='mi_modulo')
>>> funcion_uno = PythonFunction(name='f1()',
                   module_id=modulo.id)
>>> funcion_dos = PythonFunction(name='f2()',
                   module_id=modulo.id)

En los ejemplos anteriores a medida que ibamos creando objetos de la clase “PythonFunction”, le ibamos asignando el id del objeto modulo, para crear el correcto mapeo de la relacion que queremos realizar, y hacemos esto porque la claves foraneas en las bases de datos son establecidas con el id, pero como estamos utilizando SQLObject, podemos pasarle la referencia del objeto mismo,
ya que éste provee un mecanismo que desecha todo lo que no le interesa y toma lo que si.
Muestro con un ejemplo.

>>> funcion_tres = PythonFunction(name='f3()',
                    module_id=modulo)

Relaciones binarias con multiplicidad 1..1 (one-to-one)
En SQLObject para establer este mapeo es muy similar al caso anterior, solo que no llevaría el MultipleJoin
Si fuera el caso que una funcion de python tuviera solo un metodo, lo que tendriamos es algo como:

>>> class PythonFunction(SQLObject):
...    name = StringCol()
...    modulo_id = ForeignKey('PythonModule')
>>> class PythonModule(SQLObject):
...    name = StringCol()
...    function = ForeignKey('PythonFunction')
>>>

Relaciones binarias con multiplicidad m..n (many-to-many)
Esta explicacion se las debo :P ya que no lo utilizé todavia. Solo se que el proceso es muy similar a lo que les conte antes, solo que tenemos que usar RelatedJoin

Relaciones trinarias
Estas relaciones al momento de crear las clases para la base de datos se convierte inexorablemente en una clase más, la cual contendrá como atributos las claves foráneas de las entidades que la componen.

A medida que valla avanzando mas, si modiico algo ó simplemente aprendo algunas cosillas mas les cuento.