Opened 4 years ago

Closed 4 years ago

#31669 closed Bug (invalid)

migrate --fake-initial doesn't work when only a subset of tables exists in database.

Reported by: Sara Correia Owned by: nobody
Component: Migrations Version: 3.0
Severity: Normal Keywords:
Cc: Michael XU Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hi,
I have a migration file with the creation of two models: A and B. The database already has the table corresponding to the model A.
So, when I run the command python manage.py migrate --fake-initial I get an exception "jango.db.utils.ProgrammingError: relation "A" already exists.
The migration should ignore the existing tables, but crate the new ones. Otherwise, it's impossible to have a initial migration file with existing tables and new ones.
Sara

Change History (2)

comment:1 by Michael XU, 4 years ago

Cc: Michael XU added

Hi - I can confirm this behavior, but I think it is the intended behavior.

The migration should ignore the existing tables, but crate the new ones.

I feel like this quote above is not the intended behavior. In the doc it mentions two conditions:

Note that this only works given two things:

  • You have not changed your models since you made their tables. For migrations to work, you must make the initial migration first and then make changes, as Django compares changes against migration files, not the database.
  • You have not manually edited your database - Django won’t be able to detect that your database doesn’t match your models, you’ll just get errors when migrations try to modify those tables.

To me, it would sound like your case has violated at least one of the conditions - perhaps model B has been added after the tables were made? There are other possibilities, of course.


On another hand, looking at the code, when we do python manage.py migrate --fake-initial, it will check if all the tables and columns mentioned in the migration file already exists in the database, and if not, it will, as it says in the comment, "Alright, do it normally", which would then throw the error you have seen: django.db.utils.OperationalError: table "<...>" already exists.

In this sense, fake-initial seems to only be fake with an additional check: That all the tables and columns are already in your database, and if this is not satisfied, it will try to apply the migrations as usual.

comment:2 by Mariusz Felisiak, 4 years ago

Resolution: invalid
Status: newclosed
Summary: migrate --fake-initial doesn't work when only a subset of tables exists in databasemigrate --fake-initial doesn't work when only a subset of tables exists in database.

This is an intended and documented behavior.

Note: See TracTickets for help on using tickets.
Back to Top