[PonyORM-list] Cannot save cyclic chain

Alexander Kozlovsky alexander.kozlovsky at gmail.com
Sun Nov 2 20:41:55 UTC 2014


Hi Arthur!

When Pony stores objects to the database, it needs to determine the order
of inserts. This order of inserts cannot be arbitrary, because of
referential integrity constraints. We cannot insert a row which references
to another row, if that another row is not exists in the database yet.

In simple cases Pony can determine valid order of inserts
automatically. But in your example there are cyclic references between
objects. Pony cannot insert object `ID` with primary key "a", because Pony
doesn't know which value to write to the `canonicalEquivalent` column
(because the `EquivalentIDset` object is not exists in the database yet).
But Pony cannot first save `EquivalentIDset` object also, because
referential integrity rules prevent it to store value of "a" in
`canonicalID` attribute.

In order to break the cycle you can perform `flush()` command before
creating `EquivalentIDset` object:

    a = ID(identifier='a')
    b = ID(identifier='b')
    flush()
    EquivalentIDset(equivalentIDs=[a, b], canonicalID=a)

The `flush()` command forces Pony to store already created `ID` objects. At
this moment the saving is possible, because `substituteIDs` and
`canonicalEquivalent` attributes of newly created objects don't refer to
any object yet, and contain None as a value.

After the `flush()` command is executed, Pony can save `EquivalentIDset`
object successfully, because the `ID` object referenced in the
`canonicalID` attribute is already stored in the database. After the
`EquivalentIDset` object is inserted, Pony will update `a` and `b` objects
in order to link them with newly created `EquivalentIDset` object.

Another option is to store all objects right away, but set the value of
`canonicalID` attribute separately after the `flush` command:

    a = ID(identifier='a')
    b = ID(identifier='b')
    idset = EquivalentIDset(equivalentIDs=[a, b])
    flush()
    idset.canonicalID = a


Regards,
Alexander


On Sun, Nov 2, 2014 at 7:57 PM, Goldberg, Arthur P <
arthur.p.goldberg at mssm.edu> wrote:

>  Hi Folks
>
> I'm building an alias dbms. Multiple aliases can refer to the same person
> (genetics subject). I've two main entities: ID, an identifier; and an
> EquivalentIDset, which points to a set of aliased IDs. EquivalentIDset
> needs to be a separate entity, so it can have attributes. One of those
> attributes is canonicalID, the primary ID (if any) among the set.
>
> However, when I set canonicalID and scan through the IDs, I get a 'Cannot
> save cyclic chain' exception. Here's an (almost) freestanding extract of my
> code that generates the error:
>
>
>
> What does the exception mean?
>
> What's the best way to handle this? My thought is to not define
> canonicalID as an entity reference, but as a string equal to ID.identifier.
> But that would lose the dbms consistency benefits. Suggestions?
>
> Thanks
> Arthur
>
> PS:
> $ pip show pony
> ---
> Name: pony
> Version: 0.5.4
> Location:
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages
>
>
> _______________________________________________
> ponyorm-list mailing list
> ponyorm-list at ponyorm.org
> /ponyorm-list
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </ponyorm-list/attachments/20141102/67727515/attachment.html>


More information about the ponyorm-list mailing list