Question

I have a SQLite database with the following tables:

fits_table = Table("fits", saveddata_meta,
                         Column("ID", Integer, primary_key = True),
                         Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True),
                         Column("shipID", Integer, nullable = False, index = True),
                         Column("name", String, nullable = False),
                         Column("timestamp", Integer, nullable = False),
                         Column("characterID", ForeignKey("characters.ID"), nullable = True),
                         Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True),
                         Column("booster", Boolean, nullable = False, index = True, default = 0))

projectedFits_table = Table("projectedFits", saveddata_meta,
                            Column("sourceID", ForeignKey("fits.ID"), primary_key = True),
                            Column("victimID", ForeignKey("fits.ID"), primary_key = True),
                            Column("amount", Integer))
mapper(Fit, fits_table,
       properties = {
                     "_Fit__projectedFits" : relation(Fit,
                                                      primaryjoin = projectedFits_table.c.victimID == fits_table.c.ID,
                                                      secondaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID,
                                                      secondary = projectedFits_table,
                                                      collection_class = HandledProjectedFitList)
                     })

It's basically a relationship table that links a Fit to another Fit.

I've been trying to figure out the proper way to cascade a delete, but I cannot get it to work. I would like if a Fit is deleted, then it also deletes any rows in the relationship table where the fit ID is in either the source or victim column.

EDIT: I forgot to add what cascade flags I tried.

cascade='all, delete, delete-orphan', single_parent=True, - did not work. In face, manually deleting the relationship row also deleted the parent (whatever matched the sourceID)

cascade='delete', single_parent=True, - did not have the issue the above setting had, but still did not delete the relationship record when the Fit was deleted

cascade='all, delete', single_parent=True, - same as above

EDIT 2: I kept fiddling with it, and without adding a cascade attribute, it kinda works. Let me explain:

If I have Fit B linked to Fit A (A is parent in this case), then delete Fit B, it does not delete the relationship. However, if I delete fit A, it does delete the relationship.

I am assuming that I have just been thinking about this completely wrong. When I have a fit instance, it gathers the relationships it has, and deletes any when that fit is deleted. However, when I delete fit B, it technically doesn't have any fits that are linked to it as children. So it never delete them.

I guess a workaround would be to assign the fits that B is a child of to a dummy attribute so that it gets deleted as well. Or do some sort of post processing in the middle layer of the application. Will post back with results, though I still welcome any thoughts. =)

Was it helpful?

Solution

I figured it out. As stated in an edit to the OP, I simply had to create a new relation with the criteria swapped. This way both relationships are loaded and deleted when the fit is deleted:

mapper(Fit, fits_table,
   properties = {
                 "_Fit__projectedFits" : relation(Fit,
                                                  primaryjoin = projectedFits_table.c.victimID == fits_table.c.ID,
                                                  secondaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID,
                                                  secondary = projectedFits_table,
                                                  collection_class = HandledProjectedFitList),

                 "_Fit__projectedOnto" : relation(Fit,
                                                  primaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID,
                                                  secondaryjoin = fits_table.c.ID == projectedFits_table.c.victimID == fits_table.c.ID,
                                                  secondary = projectedFits_table,
                                                  collection_class = HandledProjectedFitList)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top