13

I've read some questions about this issue in so, also this question is not giving the correct answer for my case:

I'm adding a created_time field in my already existing models, so no date in the mysql table belonging to the model.

class Configs(models.Model):
    ...
    creation_date = models.DateTimeField(auto_now_add=True, blank=True)
    ...

I apply the migration using python manage.py makemigrations

And I get this error:

You are trying to add a non-nullable field 'creation_date' to collections without a default; we can't do that (the database needs something to populate existing rows). Please select a fix:

I tryed many options:

creation_date = models.DateTimeField(auto_now_add=True)

This one is giving the same error.

How can this migration be achieved, if USE_TZ in settings is set to False?
Btw, is this a bug in Django 1.9.4 makemigrations script?

Community
  • 1
  • 1
Evhz
  • 8,852
  • 9
  • 51
  • 69

1 Answers1

26

auto_now_add set the current datetime when the instance is created, which never happens during your migration so you are trying to leave NULL a non-nullable field.

The solution would be to add a default date to your model, makemigrations, then remove the default parameter from the model, makemigrations again and finally migrate. You can achieve the same adding null=True to the field, adding a RunPython or RunSQL to your migration that populates the field, and then remove the null=true from the field.

At the end you can merge both migration files (or simple write it yourself) to end with something like:

operations = [
    migrations.AddField(
        model_name='configs',
        name='creation_date',
        field=models.DateTimeField(auto_now_add=True, null=True, blank=True),
    ),
   migrations.RunPython(populate_dates),
   migrations.AlterField(
        model_name='configs',
        name='creation_date',
        field=models.DateTimeField(auto_now_add=True, blank=True),
    ),
]

I just wrote it so I hope it does not have many typos

dnaranjo
  • 3,647
  • 3
  • 27
  • 41
  • 1
    The point is that before setting `null=False` (or remove the argument) you need to populate all the existing rows. You can achieve this by doing what I explained above. Did you do it and still get the same error? – dnaranjo May 31 '16 at 09:49
  • 1
    Thanks, the sentence: `field=models.DateTimeField(auto_now_add=True, null=True, blank=True)` did solve my problem once previously created_time attributes were removed from the db structure. – Evhz May 31 '16 at 14:31
  • @Evhz: Works for me, too, in Django 3.2. When solved, `auto_now_add=False` **shows** the field in `admin/model//change` (open for edit), and the same for `auto_now=False`, while the field is hidden in admin *change* view, when `=True` (not available for edit). This behavior may differ from [Django documentation](https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.DateField.auto_now_add), or I can not read docs precisely? – Morten Engelsmann Jul 31 '21 at 12:09