I have a model LucyGuide
which extends Django's User
model through a OneToOneField
:
class LucyGuide(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
There is also a Company
model which has a field called lucy_guide
which is a ForeignKey
to the User
model:
class Company(models.Model):
lucy_guide = models.ForeignKey(User)
I'd like to change this to
class Company(models.Model):
lucy_guide = models.ForeignKey(LucyGuide)
However, when I implement this change and make and run migrations, I run into an IntegrityError
:
django.db.utils.IntegrityError: insert or update on table "lucy_web_company" violates foreign key constraint "lucy_web_company_lucy_guide_id_de643702_fk_lucy_web_"
DETAIL: Key (lucy_guide_id)=(461) is not present in table "lucy_web_lucyguide".
This question is similar to IntegrityError Insert or update on table "orders_order" violates foreign key constraint " ; it seems like I have created LucyGuide
objects before referencing them as foreign keys.
What is the best way to fix this? Is there a series of commands I need to write in the shell to create these users?
Update
From looking around in the shell, it seems like Django still expects the same numerical id
s for the ForeignKey
, even though the model has changed (from User
to LucyGuide
). Here are the ids
of User
s which are also LucyGuide
s:
In [11]: lucy_guide_users = [user for user in User.objects.all() if hasattr(user, 'lucyguide')]
In [16]: [user.id for user in lucy_guide_users]
Out[16]: [12, 8, 461, 497, 500, 471, 475, 495]
Notice that this contains the id
of 461
from the error. The id
s of LucyGuide
s, however, are simply
In [17]: [guide.id for guide in LucyGuide.objects.all()]
Out[17]: [1, 2, 3, 4, 5, 6, 7, 8]
It seems like the way to fix this is to change the primary keys of the LucyGuide
s, but it seems from What is the best approach to change primary keys in an existing Django app? that this is a very involved process. Is there a simpler way?
You can't simply change the target of the foreign key. For each existing company, you need to change lucy_guide_id
from the related user's id to the related lucy_guide's id. Django can't do this for you.
You could do the migration in several steps. First, add a new foreign key and create a migration
class Company(models.Model):
lucy_guide = models.ForeignKey(User)
new_lucy_guide = models.ForeignKey(LucyGuide, blank=True, null=True)
Next, create a data migration to populate the new_lucy_guide
field.
Then you can drop the lucy_guide
field, and create a migration.
class Company(models.Model):
new_lucy_guide = models.ForeignKey(LucyGuide, blank=True, null=True)
Finally you can rename your field and create a migration:
class Company(models.Model):
lucy_guide = models.ForeignKey(LucyGuide, blank=True, null=True)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.