﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
30269	AlterField in database_operations of SeparateDatabaseAndState migration doesn't set NOT NULL constraint for PostgreSQL	Dmitrii Prihodco	nobody	"For changing a field, and not having some unpredictable behavior we employ multi-stage deployments.

So for example we have a field:
{{{
name = models.CharField(max_length=255, null=True)
}}}

And we want to make it non-nullable. To make it so we perform two migrations, firstly the state:

{{{
    operations = [
        # Plus whatever data migration is needed for the NULL values
        migrations.SeparateDatabaseAndState(
            state_operations=[
                migrations.AlterField(
                    model_name='testmodel',
                    name='name',
                    field=models.CharField(max_length=255)
                )
            ]
        )
    ]
}}}

After all parts of the system have been updated with code that handles the given field only in a non-nullable way, we can safely set it to NON NULL in the database:

{{{
    operations = [
        migrations.SeparateDatabaseAndState(
            database_operations=[
                migrations.AlterField(
                    model_name='testmodel',
                    name='name',
                    field=models.CharField(max_length=255)
                )
            ]
        )
    ]
}}}

But the last migration doesn't actually perform any changes, the field remains nullable in the database. This can be circumvented by using migrations.RunSQL, but one can easily miss out the need to do that.

PostgreSQL in use: 9.6 official docker image.
Originally found for Django 1.8, reproduced for Django 2.1.7.

Didn't reproduce with SQLite.
"	Bug	closed	Migrations	2.1	Normal	invalid			Unreviewed	0	0	0	0	0	0
