Opened 4 years ago
Last modified 4 years ago
#31686 closed New feature
SQL migrations don't set default in database, but would be handy — at Initial Version
Reported by: | Rik | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.0 |
Severity: | Normal | Keywords: | sql migrations default not null |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When you create a model with a default value and you make migrations for it and migrate it, they the database schema won't have a default. For Django it doesn't matter because the default is on the model. However, if you want to execute the database migrations before you deploy the new code, the old code should not crash with the new database schema. If you add a column that is NOT NULL
and you don't set a default value, then the old version of the code, that doesn't know about the new column, won't be able to add a new row because it doesn't provide a value for the new column that cannot be NULL
. You'll get an SQL error saying the column cannot be null.
Data migrations don't fix this, they update existing rows, you still have the problem if the old version of the code tries to add a new row to the table with the new schema. To make the new table schema backwards compatible we need to set a default value on the new column. Or it should allow NULL
values of course, but this is not always what you want.
I have found the location in the code where this should be fixed. This line in the code sets drop=True
which drops the default value from a column. This seems to happen if the column type support default values and if there is a default value set on the model. So Django always gets rid of the default value in the database.
It would be great if we can add a database settings where you can tell Django to also set the default in the database. Something like:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '5432', 'SET_COLUMN_DEFAULTS': True } }