1

The problem is slightly tricky to define so please bear with me.

I have a model called Blog. I have three migrations in it.

0001_initial: Create the table for Blog

0002_seed_data: Seed some data into this table. To seed this data, I use:

all_blogs = Blog.objects.all()
 for blog in all_blogs.iterator():
  #some logic here
  blog.save()

0003_add_column: Add a new column 'title' to this table

When I run 0003_add_column on a database where 0002_seed_data has already run in the past, it works.

But when I run these migrations on an empty database, it fails at 0002_seed_data because it cannot find a title in the database. It gives an error similar to:

django.db.utils.OperationalError: (1054, "Unknown column 'Blog.title' in 'field list'")

This looks like a chicken an egg problem to me because 0002 cannot run until title column isn't present in the table. There is provision to add a title in the table in 0003, but that cannot run until 0002 has run. A simple solution is to correct the order. This is what I have been doing in the past. But this means everytime I add a new column to this table, its order has to be corrected.

A quick search of the error returns a few solutions and most of them talk about deleting all migrations and making them again using makemigrations. This will not solve my problem

So is there a better way of doing this?

Nazim Kerimbekov
  • 4,712
  • 8
  • 34
  • 58
Varun Singh
  • 1,135
  • 13
  • 18

2 Answers2

3

You haven't shown your migration files, but I would guess that you are importing your Blog class from your models file. As you have seen, you can't do that because it is out of sync with the state of the database at that point in the migration process.

Luckily, Django migrations support "historical" models which represent the model correctly based on the state of the db. Instead of importing your model, you get it programmatically inside your RunPython function by calling apps.get_model(). So:

def my_function(apps, schema_editor):
    Blog = apps.get_model('myapp', 'Blog')
    all_blogs = Blog.objects.all()
    ...

See the docs on data migrations.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
-2

You should use the SQL command for the changing anything in DB. You can use python library, the error is coming, because you using the Django class model, which have the now title field but when it is trying to find that value at that time there is no value, so better fetch the value from SQL query , perform whatever operation you want to perform on that.

aman kumar
  • 3,086
  • 1
  • 17
  • 24