Undoing a migration for a duplicate field

We have had a duplicate field added to of our Django Wagtail models which has confused the migration system.

The following was added to one of the models while back along with a migration that added a singular instance of the field:

    stream = fields.StreamField(
        who_fund_blocks,
        blank=True,
        verbose_name="Additional content",
    )
    stream = fields.StreamField(
        who_fund_blocks,
        blank=True,
        verbose_name="Additional content",
    )

This all seemed to be fine, and the project continued with new fields and migrations being added elsewhere without any problem.

Then the duplicate field was spotted and removed from the models page.

Now, if we try to add a field on some model and a migration for it, the migration is created but doesn't complete, although there are no errors that directly imply it has failed:

(.venv)  development  ➜ app 🐟 manpy migrate
/root/.cache/pypoetry/virtualenvs/.venv/lib/python3.10/site-packages/wagtail/utils/widgets.py:10: RemovedInWagtail70Warning: The usage of `WidgetWithScript` hook is deprecated. Use external scripts instead.
  warn(
System check identified some issues:

WARNINGS:
?: (urls.W005) URL namespace 'freetag_chooser' isn't unique. You may not be able to reverse all URLs in this namespace
?: (urls.W005) URL namespace 'pagetag_chooser' isn't unique. You may not be able to reverse all URLs in this namespace
?: (urls.W005) URL namespace 'sectiontag_chooser' isn't unique. You may not be able to reverse all URLs in this namespace
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, core, csp, django_cron, donations, importers, sessions, submissions, taggit, taxonomy, users, wagtail_localize, wagtailadmin, wagtailcore, wagtaildocs, wagtailembeds, wagtailforms, wagtailimages, wagtailredirects, wagtailsearch, wagtailsearchpromotions, wagtailusers
Running migrations:
  Applying core.0019_utilitypage_show_navigation_bar_and_more...

The same thing happens if we add the duplicate stream field back and create a new migration i.e. the migration looks like it runs ok but there's no confirmation tick.

And when I start the server we get:

You have 1 unapplied migration(s). Your project may not work properly until you apply the migration for app(s): core.
Run 'python manage.py migrate' to apply them.

The database appears to have the field already but the migrations system wants to try to add it again but can't and this is blocking all other migrations.

If I comment out both stream fields, migrations can be made, but the site breaks on the page where the database expects a stream field to be present. I suppose I could delete the stream fields and manually drop the stream field in the database, though we would lose some data by doing that, and I'd prefer to fix this with Django and migrations.

Any idea how to unpick this?

It's a little difficult to give advice without seeing your migration files and database. It sounds like your database table only has one copy of stream, right? So once you remove the duplication in the model file, the database table and your python model will match.

Assuming that's your situation, then I would edit your old migration files to remove mention of the duplicate. Then try running migrate and makemigrations + migrate on a copy of your production database until you are satisfied that everything works as you want it to.

If your table has duplicate columns, my first question is how could that have happened and my second would be what database are you using? I am fairly sure you can't have duplicate columns in the database but if so, it will be a longer conversation.

Back to Top