Search code examples
djangosqlitedjango-modelsdjango-migrations

python manage.py migrate --fake <appname> vs python manage.py migrate --fake <appname> zero


When I run python manage.py migrate --fake photos zero :

Operations to perform:
Unapply all migrations: photos Running migrations: Rendering model states... DONE
Unapplying photos.0001_initial... FAKED

After running above command, I ran python manage.py migrate at that time this error occurred.

Traceback:Traceback (most recent call last):

File "C:\Users...\lib\site-packages\django\db\backends\sqlite3\base.py", line 411, in execute return Database.Cursor.execute(self, query)

django.db.utils.OperationalError: table "photos_userphoto" already exists

When I run python manage.py migrate --fake photos:

Operations to perform: Apply all migrations: photos Running migrations: Applying photos.0001_initial... FAKED Applying photos.0002_auto_20210303_0120... FAKED

After running above command, I ran python manage.py migrate and this work perfectly.

Running migrations:
  Applying photos.0003_auto_20210303_0123... OK

So my question is that what difference between python manage.py migrate --fake <appname> vs python manage.py migrate --fake <appname> zero and Why first command throws me an error?

Thank you..


Solution

  • You appear to have a misunderstanding about the --fake flag. According to the documentation the --fake flag:

    Marks the migrations up to the target one (following the rules above) as applied, but without actually running the SQL to change your database schema.

    It also further states that it is meant for advanced users if they are making changes manually. Basically Django makes a table django_migrations to manage your migrations. It adds an entry to it to mark if a migration has been applied. What --fake does is simply add / remove the entries to / from this table according to the migration you specify. Also the zero means to undo all migrations.

    python manage.py migrate --fake photos zero
    

    The above command means you basically say to Django:

    I have or will manually remove(d) all the tables, etc. from the database for the app photos

    python manage.py migrate --fake <appname>
    

    In the above command you don't specify the migration (in previous you specified zero), this means to assume that you mean till the most recent migration. Basically with --fake this command means:

    I have or will manually make all the tables, etc. in the database for the migrations till the most recent one.

    From my understanding you only made some changes and wanted to update your database, for this you could have simply written:

    python manage.py migrate