pythondjangopostgresqlmigratemakemigrations

Django makemigrations tool fails if i change the foreign key / other relationships at models


I have a problem with Djang makemigrations / migrate tool

  1. I have a Withdraw model with foreignkey to an Employee table. Everything is working fine

models.py

from django.contrib.auth.models import User

class Withdraw(models.Model):
    employee_id = models.ForeignKey(Employee, on_delete = models.PROTECT)
    amount = models.IntegerField(default=0)
    withdraw_date = models.DateTimeField(default=timezone.now)
    is_confirmed_by_employer = models.BooleanField(default=False)
  1. I want to change it and have user as a foreignkey to user:

    user = models.ForeignKey(User, on_delete=models.CASCADE)

  2. I run makemigrations and I have this errormessage:

You are trying to add a non-nullable field 'user' to withdraw without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows with a null value for this column) 2) Quit, and let me add a default in models.py

  1. If I press 1, then I have the following message, what I dont really get, why shall I put datetime or timezone.now to user??

Select an option: 1 Please enter the default value now, as valid Python The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now Type 'exit' to exit this prompt

  1. I tried to delete migrates folder and recreate migration files as was adviced in some other forum posts. When I recreate the migrations with createmigrations Withdraw command and migrate it to postgresSql the Withdraw table is not created however the tool is writing that the table is created and migrated.

So Either way, Im not able to migrate this small change to the DB. Do you have any opinions? Thx!


Solution

  • Yes this is natural behavior.

    What happened here is, When first you made other rows in database (earlier before making User field) User field was not there, and now when you are adding a User field in this database you are not setting it to null or blank so Django asks "what about previous saved rows? They can't be null." So best option was to fill those fields by providing one off default value. To do that you had to choose option 1 and then fill those missing spaces.

    I do not recommend answer given by @jTiKey as if you allow users field to be blank or null, user could withdraw without giving in Users field and I think you'll not want that.