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 toNone
- 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....
精彩评论