Opened 3 years ago

Closed 3 years ago

#33108 closed Cleanup/optimization (wontfix)

Makemigrations allows on-off default when adding non-nullable unique field

Reported by: Julian-Samuel Gebühr Owned by: nobody
Component: Migrations Version: 3.2
Severity: Normal Keywords: migrations
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Reproduce

Create a model like

class Book(models.Model):
    title = models.CharField(max_length=200)

and apply with makemigrations and migrate, then add a book to the database. Now extend the book model by a unique, non-nullable field (e.g.) ISBN

class Book(models.Model):
    title = models.CharField(max_length=200)
    isbn = models.CharField('ISBN', max_length=13, unique=True, help_text='ISBN number (13 Characters)')

To apply these changes you try makemigrations which tells you

You are trying to add a non-nullable field 'isbn' to book without a default; we can't do that (the database needs som
ething 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

Choosing 1) and using a default value let's you finish but then migrate fails with

django.db.utils.IntegrityError: (1062, "Duplicate entry '1234567890123' for key 'isbn'")

Expected Behaviour

I would expect makemigrations to say something in the line of

You can't add make a field unique when not all entries in the database have a unique value for this field. A solution might be to remove the unique constraint and add a unique value for this field to all entries. Then re-add the unique constraint.

and fail to make the migration.

Change History (1)

comment:1 by Mariusz Felisiak, 3 years ago

Resolution: wontfix
Status: newclosed
Type: BugCleanup/optimization

Thanks for the report.

... and fail to make the migration.

This is not an expected behavior, because you can add a column to an empty table or a table with a single row. In both cases it works fine. Moreover we already inform users that provided value "...will be set on all existing rows with a null value for this column". Also, it's documented in details how to deal with such migration.

Note: See TracTickets for help on using tickets.
Back to Top