Migration weird behaviour -> field does not exist but everything is correct

I have correctly defined two migrations, first one calls a command that queries our Workspace model, the second one adds a field to our Workspace model.

When running the two together, I get this error:

File "/root/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column workspace.asd does not exist
LINE 1: ...randing_options", "workspace...

Lets look at the files.

First migration:

# Generated by Django 4.2.17 on 2025-02-10 19:26

from django.db import migrations
from django.core.management import call_command

def execute_test(apps, schema_editor):
    call_command('execute_test')

class Migration(migrations.Migration):

    dependencies = [
        ("workspace", "0147_workspace_feature_flag_presentation_pdf_export"),
    ]

    operations = [
        migrations.RunPython(execute_test, reverse_code=migrations.RunPython.noop)
    ]

Second migration:

# Generated by Django 4.2.17 on 2025-02-10 19:30

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ("workspace", "0148_auto_20250210_2026"),
    ]

    operations = [
        migrations.AddField(
            model_name="workspace",
            name="asd",
            field=models.CharField(blank=True, max_length=255, null=True),
        ),
    ]

execute_test.py:

from django.core.management import BaseCommand
from workspace.models import (
    Workspace,
)


class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument(
            "--force",
            action="store_true",
        )
        parser.add_argument(
            "--verbose",
            action="store_true",
        )

    def handle(self, *args, **options):
        force = options["force"]
        verbose = options["verbose"]

        workspaces = Workspace.objects.all()
        for workspace in workspaces:
            workspace.name_workspace = workspace.name_workspace
            workspace.save()
        self.stdout.write(self.style.SUCCESS("\n\nFinish fix_users_without_membership"))

This migrations and command was just to reproduce this error that we’ve been having

Why do you consider this “weird” behavior?

At the time the first migration is running, you have a definition in your Workspace model for a field named asd - but that field has not yet been added to the database. So the access to that model in your management command is going to fail.

In order for this to work the way I believe you want it you, you will need to run that logic directly in your migration file using the historical models. (Either that, or figure out a way to pass those historical models through to your management command.)

See: Historical models

you’re right, makes total sense. Thank you!