Re: one-to-one association, howto

Sebastien Bigaret <[email protected]> 17 Feb 2005 12:34:43 +0100
Newsgroups gmane.comp.python.modeling
Message-ID <[email protected]>
        Hi,

Wara Songkran <[email protected]> wrote:
> I've try to create one-to-one association from table Task to Supplier by =
define
>=20
> model.association =3D [
>   Association('Task', 'Supplier',multiplicity=3D[ [0, 1], [0, 1] ])
> ]
>=20
> but the error said=20
>=20
> ValueError: invalid multiplicity dst->src: should be toMany
>=20
> I've also apply the patch from
> http://sourceforge.net/mailarchive/message.php?msg_id=3D9401573
>=20
> Did I done something wrong?


The problem is that one-to-one relationships are still not supported
out of the box, at least not the way one think they should be :/

For the moment one-to-one rels. should be modeled as one-to-many
(http://modeling.sourceforge.net/UserGuide/design-rels.html)

Back to your example, your model becomes::

  model.association =3D [
    ## this is in fact a one-to-one modeled as a one-to-many,
    ## class 'Supplier' defines getTask() and setTask()
    Association('Task', 'Supplier',multiplicity=3D[ [0, 1], [0, None] ],
                relations=3D['supplier', 'tasks'] )
  ]

and then you add to the class Supplier the following code::
=20=20
   def validateTasks(self, aValue):
     """
     ``tasks`` is a to-one relationship modeled as a to-many (inverse of
     the to-one rel ``Task.supplier``): it is valid iff it has no more
     than one element

     :exception Modeling.Validation.ValidationException: if more than one
       task is registered
     :see: `getTask()`, `setTask()`
     """
     # see http://modeling.sf.net/UserGuide/customobject-validation-by-key.=
html
     # subsection 3.3.2.2.
     from Modeling import Validation
     if len(self.getTasks())>1:
       raise Validation.ValidationException
     return
=20=20
  def getTask(self):
    if self.getTasks():
        return self.getTasks()[0]
    return None
=20=20
  def setTask(self, task):
    if self.getTask():
      self.removeFromTasks(self.getTask())
    self.addToTasks(task)

  # you can also define the corresponding property:
  task =3D property(getTask, setTask, None, "to-one relationship to Task")


Additional note: with this definition you'll have a foreign key in entity
  'Task' pointing to the primary key in entity 'Supplier'.  It seems
  reasonable, but in case you want the inverse, swap tasks and supplier in =
the
  association's definition and define get/setSupplier() in class Task.

        Regards,

-- S=E9bastien.



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click