[Django] #33566: Issue with migrations after upgrading Django 2 to Django 3.2.

65 views
Skip to first unread message

Django

unread,
Mar 8, 2022, 6:07:39 AM3/8/22
to django-...@googlegroups.com
#33566: Issue with migrations after upgrading Django 2 to Django 3.2.
-------------------------------------+-------------------------------------
Reporter: Ismael | Owner: nobody
Jerez |
Type: Bug | Status: new
Component: | Version: 3.2
Migrations | Keywords: orm, migrate,
Severity: Normal | makemigrations, database,
Triage Stage: | migrations, migration
Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Hi,

I recently upgraded from Django 2 to Django 3.2.

Everything works fine but when I execute “migrate” as a manage.py command,
it always says “Your models in app(s): ‘admin’, ‘auth’, ‘base’,
‘contenttypes’, ‘sessions’ have changes that are not yet reflected in a
migration, and so won’t be applied.
Run ‘manage.py makemigrations’ to make new migrations, and then re-run
‘manage.py migrate’ to apply them.”

If I execute “makemigrations” commands I always get “No changes detected”.

I downgrade to Django2, the message is gone.

I have every mentioned app on my INSTALLED_APPS variable in settings. As
you can see only ‘base’ app is one of mine, the rest are default Django
apps.

I am using Oracle 19 database that can not be recreated.

I hope you can help me or give me some ideas of what is happening and why
am I receiving that message from “migrate” command.

Thank you in advance,
Ismael.

--
Ticket URL: <https://code.djangoproject.com/ticket/33566>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Mar 8, 2022, 7:16:14 AM3/8/22
to django-...@googlegroups.com
#33566: Issue with migrations after upgrading Django 2 to Django 3.2.
-------------------------------------+-------------------------------------
Reporter: Ismael Jerez | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 3.2
Severity: Normal | Resolution: needsinfo
Keywords: orm, migrate, | Triage Stage:
makemigrations, database, | Unreviewed
migrations, migration |

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => needsinfo


Comment:

Hi, I don't think you've explained the issue in enough detail to confirm a
bug in Django. Can you provide a sample project showing a fault in Django?

--
Ticket URL: <https://code.djangoproject.com/ticket/33566#comment:1>

Django

unread,
Jun 8, 2022, 4:17:05 AM6/8/22
to django-...@googlegroups.com
#33566: Issue with migrations after upgrading Django 2 to Django 3.2.
-------------------------------------+-------------------------------------
Reporter: Ismael Jerez | Owner: nobody
Type: Bug | Status: new

Component: Migrations | Version: 3.2
Severity: Normal | Resolution:
Keywords: orm, migrate, | Triage Stage:
makemigrations, database, | Unreviewed
migrations, migration |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ismael Jerez):

* status: closed => new
* resolution: needsinfo =>


Comment:

Hi again:

Sorry, it's been a while. I cannot share my code due to confidentiality,
but I think I found a solution.

I was debugging migrate command to see what changes are being detected.
Then, I have called write_migration_files(changes) from makemigrations
command using the changes detected before. After this, I have new
migrations created for the mentioned apps. Most of the changes are only
verbose_name related (Spanish translations) and minor updates, so I think
it should be safe to migrate.

The question is: why did migrate command detect these changes (see below)
but makemigrations did not? I think both changes autodetector should work
the same way to avoid problems like this one.

These are the changes detected by migrate command (but not by
makemigrations) related to Django default apps:
admin app:

{{{
# Generated by Django 3.2.13 on 2022-06-08 07:39

from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('base', '0012_auto_20220608_0939'),
('contenttypes', '0003_auto_20220608_0939'),
('admin', '0003_logentry_add_action_flag_choices'),
]

operations = [
migrations.AlterModelOptions(
name='logentry',
options={'ordering': ['-action_time'], 'verbose_name':
'entrada de registro', 'verbose_name_plural': 'entradas de registro'},
),
migrations.AlterField(
model_name='logentry',
name='action_flag',
field=models.PositiveSmallIntegerField(choices=[(1,
'Añadido'), (2, 'Modificar'), (3, 'Borrado')], verbose_name='marca de
acción'),
),
migrations.AlterField(
model_name='logentry',
name='action_time',
field=models.DateTimeField(default=django.utils.timezone.now,
editable=False, verbose_name='hora de la acción'),
),
migrations.AlterField(
model_name='logentry',
name='change_message',
field=models.TextField(blank=True, verbose_name='mensaje de
cambio'),
),
migrations.AlterField(
model_name='logentry',
name='content_type',
field=models.ForeignKey(blank=True, null=True,
on_delete=django.db.models.deletion.SET_NULL,
to='contenttypes.contenttype', verbose_name='tipo de contenido'),
),
migrations.AlterField(
model_name='logentry',
name='object_id',
field=models.TextField(blank=True, null=True, verbose_name='id
del objeto'),
),
migrations.AlterField(
model_name='logentry',
name='object_repr',
field=models.CharField(max_length=200, verbose_name='repr del
objeto'),
),
migrations.AlterField(
model_name='logentry',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
to='base.ucauser', verbose_name='usuario'),
),
]
}}}

auth app:

{{{
# Generated by Django 3.2.13 on 2022-06-08 07:39

import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('contenttypes', '0003_auto_20220608_0939'),
('auth', '0012_alter_user_first_name_max_length'),
]

operations = [
migrations.AlterModelOptions(
name='group',
options={'verbose_name': 'grupo', 'verbose_name_plural':
'grupos'},
),
migrations.AlterModelOptions(
name='permission',
options={'ordering': ['content_type__app_label',
'content_type__model', 'codename'], 'verbose_name': 'permiso',
'verbose_name_plural': 'permisos'},
),
migrations.AlterModelOptions(
name='user',
options={'verbose_name': 'usuario', 'verbose_name_plural':
'usuarios'},
),
migrations.AlterField(
model_name='group',
name='name',
field=models.CharField(max_length=150, unique=True,
verbose_name='nombre'),
),
migrations.AlterField(
model_name='group',
name='permissions',
field=models.ManyToManyField(blank=True, to='auth.Permission',
verbose_name='permisos'),
),
migrations.AlterField(
model_name='permission',
name='codename',
field=models.CharField(max_length=100, verbose_name='nombre en
código'),
),
migrations.AlterField(
model_name='permission',
name='content_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
to='contenttypes.contenttype', verbose_name='tipo de contenido'),
),
migrations.AlterField(
model_name='permission',
name='name',
field=models.CharField(max_length=255, verbose_name='nombre'),
),
migrations.AlterField(
model_name='user',
name='date_joined',
field=models.DateTimeField(default=django.utils.timezone.now,
verbose_name='fecha de alta'),
),
migrations.AlterField(
model_name='user',
name='email',
field=models.EmailField(blank=True, max_length=254,
verbose_name='dirección de correo electrónico'),
),
migrations.AlterField(
model_name='user',
name='first_name',
field=models.CharField(blank=True, max_length=150,
verbose_name='nombre'),
),
migrations.AlterField(
model_name='user',
name='groups',
field=models.ManyToManyField(blank=True, help_text='Los grupos
a los que pertenece este usuario. Un usuario tendrá todos los permisos
asignados a cada uno de sus grupos.', related_name='user_set',
related_query_name='user', to='auth.Group', verbose_name='grupos'),
),
migrations.AlterField(
model_name='user',
name='is_active',
field=models.BooleanField(default=True, help_text='Indica si
el usuario debe ser tratado como activo. Desmarque esta opción en lugar de
borrar la cuenta.', verbose_name='activo'),
),
migrations.AlterField(
model_name='user',
name='is_staff',
field=models.BooleanField(default=False, help_text='Indica si
el usuario puede entrar en este sitio de administración.',
verbose_name='es staff'),
),
migrations.AlterField(
model_name='user',
name='is_superuser',
field=models.BooleanField(default=False, help_text='Indica que
este usuario tiene todos los permisos sin asignárselos explícitamente.',
verbose_name='estado de superusuario'),
),
migrations.AlterField(
model_name='user',
name='last_login',
field=models.DateTimeField(blank=True, null=True,
verbose_name='último inicio de sesión'),
),
migrations.AlterField(
model_name='user',
name='last_name',
field=models.CharField(blank=True, max_length=150,
verbose_name='apellidos'),
),
migrations.AlterField(
model_name='user',
name='password',
field=models.CharField(max_length=128,
verbose_name='contraseña'),
),
migrations.AlterField(
model_name='user',
name='user_permissions',
field=models.ManyToManyField(blank=True, help_text='Permisos
específicos para este usuario.', related_name='user_set',
related_query_name='user', to='auth.Permission', verbose_name='permisos de
usuario'),
),
migrations.AlterField(
model_name='user',
name='username',
field=models.CharField(error_messages={'unique': 'Ya existe un
usuario con este nombre.'}, help_text='Requerido. 150 carácteres como
máximo. Únicamente letras, dígitos y @/./+/-/_ ', max_length=150,
unique=True,
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
verbose_name='nombre de usuario'),
),
]
}}}

contenttypes app:

{{{
# Generated by Django 3.2.13 on 2022-06-08 07:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('contenttypes', '0002_remove_content_type_name'),
]

operations = [
migrations.AlterModelOptions(
name='contenttype',
options={'verbose_name': 'tipo de contenido',
'verbose_name_plural': 'tipos de contenido'},
),
migrations.AlterField(
model_name='contenttype',
name='model',
field=models.CharField(max_length=100, verbose_name='nombre de
la clase modelo de python'),
),
]
}}}

sessions app:

{{{
# Generated by Django 3.2.13 on 2022-06-08 07:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('sessions', '0001_initial'),
]

operations = [
migrations.AlterModelOptions(
name='session',
options={'verbose_name': 'sesión', 'verbose_name_plural':
'sesiones'},
),
migrations.AlterField(
model_name='session',
name='expire_date',
field=models.DateTimeField(db_index=True, verbose_name='fecha
de caducidad'),
),
migrations.AlterField(
model_name='session',
name='session_data',
field=models.TextField(verbose_name='datos de sesión'),
),
migrations.AlterField(
model_name='session',
name='session_key',
field=models.CharField(max_length=40, primary_key=True,
serialize=False, verbose_name='clave de sesión'),
),
]
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/33566#comment:2>

Django

unread,
Jun 9, 2022, 4:58:33 AM6/9/22
to django-...@googlegroups.com
#33566: Issue with migrations after upgrading Django 2 to Django 3.2.
-------------------------------------+-------------------------------------
Reporter: Ismael Jerez | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 3.2
Severity: Normal | Resolution: needsinfo

Keywords: orm, migrate, | Triage Stage:
makemigrations, database, | Unreviewed
migrations, migration |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* status: new => closed
* resolution: => needsinfo


Comment:

Thanks for the follow-up.

How are you setting language for your project? Do you have any
customisations there at boot-up?

I'm struggling to get the options translated into Spanish at all (in
`migrate` or `makemigrations`):

{{{


options={'verbose_name': 'grupo', 'verbose_name_plural':
'grupos'},
}}}

This is because both `migrate` and `makemigrations` use the private
`@no_translations` decorator
([https://github.com/django/django/blob/c32858a8ce961d276215a040ae0ab1e4409b70f8/django/core/management/base.py#L87
src]).

The only way I've managed to reproduce your error is by disabling that and
then adding `LANGUAGE_CODE = "es"` to settings.
However if I do that, the change applies equally to `makemigrations`.

I was able to reproduce that with a stock fresh project created with
`startproject`, so you should be able to do the same, but it looks like
you must have some customisation in play that you've not specified here.
If you can include it in a minimal sample project, happy to have a look.

--
Ticket URL: <https://code.djangoproject.com/ticket/33566#comment:3>

Django

unread,
Jun 10, 2022, 2:42:03 AM6/10/22
to django-...@googlegroups.com
#33566: Issue with migrations after upgrading Django 2 to Django 3.2.
-------------------------------------+-------------------------------------
Reporter: Ismael Jerez | Owner: nobody
Type: Bug | Status: new

Component: Migrations | Version: 3.2
Severity: Normal | Resolution:
Keywords: orm, migrate, | Triage Stage:
makemigrations, database, | Unreviewed
migrations, migration |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ismael Jerez):

* status: closed => new
* resolution: needsinfo =>


Comment:

Hi:

Thanks you for your reply. I don't have any customisation. About
internationalisation this is my setting:

{{{
LANGUAGE_CODE = 'es-es'

TIME_ZONE = 'Europe/Madrid'

USE_I18N = True

USE_L10N = True

USE_TZ = True
}}}

I test it removing these options so makemigrations generates new
migrations like reverting verbose_name to English but anyway when I run
migrate after that I still getting the message about changes not reflected
in a migration...

I don't think the rest of my variables could take affect on migrations.

My last try:
I edited makemigrations command replacing commenting some lines just as
migrate command:

{{{
autodetector = MigrationAutodetector(
loader.project_state(),
ProjectState.from_apps(apps),
# questioner,
)
}}}

{{{
changes = autodetector.changes(
graph=loader.graph,
# trim_to_apps=app_labels or None,
# convert_apps=app_labels or None,
# migration_name=self.migration_name,
)

}}}

After this and removing internationalisation settings, it generates all
these migrations:
{{{
Migrations for 'contenttypes':
venv2\lib\site-
packages\django\contrib\contenttypes\migrations\0004_auto_20220610_0826.py
- Change Meta options on contenttype
- Alter field model on contenttype
Migrations for 'sessions':
venv2\lib\site-
packages\django\contrib\sessions\migrations\0003_auto_20220610_0826.py
- Change Meta options on session
- Alter field expire_date on session
- Alter field session_data on session
- Alter field session_key on session
Migrations for 'auth':
venv2\lib\site-
packages\django\contrib\auth\migrations\0014_auto_20220610_0826.py
- Change Meta options on group
- Change Meta options on permission
- Change Meta options on user
- Alter field name on group
- Alter field permissions on group
- Alter field codename on permission
- Alter field content_type on permission
- Alter field name on permission
- Alter field date_joined on user
- Alter field email on user
- Alter field first_name on user
- Alter field groups on user
- Alter field is_active on user
- Alter field is_staff on user
- Alter field is_superuser on user
- Alter field last_login on user
- Alter field last_name on user
- Alter field password on user
- Alter field user_permissions on user
- Alter field username on user
Migrations for 'admin':
venv2\lib\site-
packages\django\contrib\admin\migrations\0005_auto_20220610_0826.py
- Change Meta options on logentry
- Alter field action_flag on logentry
- Alter field action_time on logentry
- Alter field change_message on logentry
- Alter field content_type on logentry
- Alter field object_id on logentry
- Alter field object_repr on logentry
- Alter field user on logentry
}}}

These are the last three migrations generated on auth app:

{{{


from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
]

operations = [


migrations.AlterField(
model_name='group',
name='name',
field=models.CharField(max_length=150, unique=True,

verbose_name='name'),
),
]

}}}


{{{
import sys

from django.core.management.color import color_style
from django.db import IntegrityError, migrations, transaction
from django.db.models import Q

WARNING = """
A problem arose migrating proxy model permissions for {old} to {new}.

Permission(s) for {new} already existed.
Codenames Q: {query}

Ensure to audit ALL permissions for {old} and {new}.
"""


def update_proxy_model_permissions(apps, schema_editor, reverse=False):
"""
Update the content_type of proxy model permissions to use the
ContentType
of the proxy model.
"""
style = color_style()
Permission = apps.get_model('auth', 'Permission')
ContentType = apps.get_model('contenttypes', 'ContentType')
alias = schema_editor.connection.alias
for Model in apps.get_models():
opts = Model._meta
if not opts.proxy:
continue
proxy_default_permissions_codenames = [
'%s_%s' % (action, opts.model_name)
for action in opts.default_permissions
]
permissions_query =
Q(codename__in=proxy_default_permissions_codenames)
for codename, name in opts.permissions:
permissions_query = permissions_query | Q(codename=codename,
name=name)
content_type_manager = ContentType.objects.db_manager(alias)
concrete_content_type = content_type_manager.get_for_model(Model,
for_concrete_model=True)
proxy_content_type = content_type_manager.get_for_model(Model,
for_concrete_model=False)
old_content_type = proxy_content_type if reverse else
concrete_content_type
new_content_type = concrete_content_type if reverse else
proxy_content_type
try:
with transaction.atomic(using=alias):
Permission.objects.using(alias).filter(
permissions_query,
content_type=old_content_type,
).update(content_type=new_content_type)
except IntegrityError:
old = '{}_{}'.format(old_content_type.app_label,
old_content_type.model)
new = '{}_{}'.format(new_content_type.app_label,
new_content_type.model)
sys.stdout.write(style.WARNING(WARNING.format(old=old,
new=new, query=permissions_query)))


def revert_proxy_model_permissions(apps, schema_editor):
"""
Update the content_type of proxy model permissions to use the
ContentType
of the concrete model.
"""
update_proxy_model_permissions(apps, schema_editor, reverse=True)


class Migration(migrations.Migration):
dependencies = [
('auth', '0010_alter_group_name_max_length'),


('contenttypes', '0002_remove_content_type_name'),
]
operations = [

migrations.RunPython(update_proxy_model_permissions,
revert_proxy_model_permissions),
]
}}}


{{{


from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('auth', '0011_update_proxy_permissions'),
]

operations = [


migrations.AlterField(
model_name='user',
name='first_name',
field=models.CharField(blank=True, max_length=150,

verbose_name='first name'),
),
]
}}}

I can paste you the rest of the migrations if you need them.

Just in case, remember I was migrating from Django 2 to Django 3.

These are my installed pip packages, just to be sure any of these are not
affecting it:
{{{
django==3.2.13
django-debug-toolbar
cx-Oracle==7.3.0
django-braces
django-tinymce==2.8.0
suds-jurko==0.6
django-bootstrap3
django-wkhtmltopdf==3.3.0
xlwt==1.3.0
ftfy==5.7
psycopg2
selenium
django-nocaptcha-recaptcha==0.0.20
zeep
}}}

Thanks you in advance,
Ismael.

--
Ticket URL: <https://code.djangoproject.com/ticket/33566#comment:4>

Django

unread,
Jun 10, 2022, 3:20:23 AM6/10/22
to django-...@googlegroups.com
#33566: Issue with migrations after upgrading Django 2 to Django 3.2.
-------------------------------------+-------------------------------------
Reporter: Ismael Jerez | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 3.2
Severity: Normal | Resolution: needsinfo

Keywords: orm, migrate, | Triage Stage:
makemigrations, database, | Unreviewed
migrations, migration |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* status: new => closed
* resolution: => needsinfo


Comment:

Thanks for the reply Ismael.

> I test it removing these options so makemigrations generates new
migrations like reverting verbose_name to English but anyway when I run
migrate after that I still getting the message about changes not reflected
in a migration...

There are two things here I can't quite make sense of:

> I test it removing these options so makemigrations generates new

migrations like reverting verbose_name to English...

So this implies the `@no_translations` decorator is not working, so there
must be some customisation in your project affecting that.

> ... anyway when I run migrate after that I still getting the message


about changes not reflected in a migration...

As per my previous comment, I can get **both** commands to apply
translations but not just one of them, as you're seeing here. (Again,
there must be a customisation somewhere in your setup, one would think)

Can you provide a sample project, created using `startproject` and adding
just enough, to recreate the issue? Otherwise it's hard to see where the
error could be.

--
Ticket URL: <https://code.djangoproject.com/ticket/33566#comment:5>

Reply all
Reply to author
Forward
0 new messages