开发者

Is a custom ForeignKey subclass necessary if the Django ORM is to work with bad PK values?

开发者 https://www.devze.com 2023-02-16 02:43 出处:网络
The project that I\'m working has dirty data in the database.Basically, the original designer created foreign key fields but didn\'t enforce them with referential integrity.Now there are FK values tha

The project that I'm working has dirty data in the database. Basically, the original designer created foreign key fields but didn't enforce them with referential integrity. Now there are FK values that are invalid and don't actually point to existent records. Normally I would simply remove these invalid FK values but the application that sits on this db additionally uses the literal number 0 stored in these FK fields to indicate other information. There is not actually a record with the primary key = 0.

I've wrapped this flawed table design in Django's ORM classes and ForeignKey fields but it, not unexpectedly, is throwing a lot of DoesNotExist exceptions when it can't find the record on the other end of the ForeignKey field. I've been trying to figure out a way to, for just this project, quietly catch this exception rather than having to litter my code with try/except blocks everywhere where this exception could be thrown. In this case I just want to prevent the error from being thrown by the Django ORM.

I'm attempting to do this with a custom manager by overriding the get() method and using the use_for_related_field=True class attribute. The custom manager's get() method isn't apparently used though in the case where the ForeignKey has an invalid key value.

class FWManager(models.Manager):
    """
    FW's data is "dirty".  Primarily it isn't enforcing referential integrity on 
    many of it's foreign key fields leading to oprphaned records.  Django throws a
    DoesNotExist exception in this case which is troublesome  having to catch it for
    any fk field access.

    Custom FWManager will silently "eat" the DoesNotExist error and return None
    instead.
    """

    use_for_related_fields=True

    def get(self, *args, **kwargs):

        #init
        retval = None

        try:
            retval = super(FWManager, self).get(*args, **kwargs)
        except:
            # silently eat errors
            pass

        return retval

I need a way to catch and eat the DoesNotExist error on potentially a custom ForeignKey and I'm looking for an example of how to handle this. Or perhaps there is a better way that someone ca开发者_Python百科n recommend.


I think there should be better possibilities to solve this, as your solution still doesn't bring any integrity to your database. Possibilities would be:

  • Change your model: set the FK's parameters to null=True and change the zeros to None
  • Set all the FKs with '0' to another value and create a related 'dummy object', representing 'deleted' objects

Silently failing on (all) exceptions can cause you also a lot of trouble, as you may run into other problems without really knowing....

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号