How to redo a migration on django 1.8 after using --fake - django

Something went wrong on my migrations, I added a new datetimefield to a model then I used makemigrations and migrate.
python manage.py makemigrations
python manage.py migrate
But after this the migrate got an "table already exists error". I supposed I could fake the migrations and start over, so I did
python manage.py makemigrations --fake core
Operations to perform:
Apply all migrations: core
Running migrations:
Rendering model states... DONE
Applying core.0001_initial... FAKED
Applying core.0002_auto_20150525_1331... FAKED
Applying core.0003_auto_20150525_1348... FAKED
Applying core.0004_processo_data_atualizacao... FAKED
but the new migrate that I've just created was faked too (of course!).
How is the proper way to redo a migration (in this case the core.0004) after doing this?

You should first set your current state to 0003 with --fake (assuming 0003 is the last migration you really have applied):
python manage.py migrate --fake core 0003
And then proceed as usual:
python manage.py migrate core
Relevant documentation: https://docs.djangoproject.com/en/dev/ref/django-admin/#migrate

Related

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..
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

Your models have changes that are not yet reflected in a migration

In django1.9, tables have been in database already, i create init migration files
python manage.py makemigrations my_app
then, i run migrate:
python manage.py migrate my_app
It shows:
psycopg2.ProgrammingError: relation "p_record_segment" already exists
I want to fake it, first, i clean the django_migrations, then excute:
python manage.py migrate my_app --fake 0001_initial
It shows:
Running migrations:
Rendering model states... DONE
Applying my_app.0001_initial... FAKED
I think this will be fine, but when i run migrate again:
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
I saw the history in django_migrations, and no changes in fact, but why django show me this.
Try using --fake-initial instead of just --fake

How to recover South from flushing db

I bulk loaded some data into my Postgresql db, only to realize all of it was a bit wrong. Keen to rectify this I flushed the db in order to reload the correct data.
Data reloaded, I made a change to a model and applied the normal ./manage.py schemamigration app --auto, and then ./manage.py migrate app (which had been working up to this point).
At this point I started getting the error:
django.db.utils.DatabaseError: relation "app_model" already exists
And the traceback appeared to be calling the initial migration file 001. So I think the answer is to do something like:
./manage.py migrate app 0005 --fake
Where the current migration that I'm looking to apply is 0006 (i.e. this is where the migrations began failing), and then the south database within postgres should be back where it was before I foolishly flushed it. At this point I should be able to
./manage.py migrate app
Can someone tell me that this approach is correct? Or if not, what the correct approach is?
After python manage.py migrate app --fake
do a python manage.py schemamigration app --auto
and then do a python manage.py migrate app
You can also make it more general:
python manage.py migrate
python manage.py flush
python manage.py migrate --fake
This will recover all the south history after flush

How to do a syncdb with django, when migrations are also involved

when I do a syncdb I get the following error everytime:
Not synced (use migrations):
- deals
- analytics
(use ./manage.py migrate to migrate these)
And when I run sudo python manage.py migrate. I get the following
Running migrations for deals:
- Nothing to migrate.
- Loading initial data for deals.
No fixtures found.
Running migrations for analytics:
- Nothing to migrate.
- Loading initial data for analytics.
No fixtures found.
I highly appreciate your help
From the output, it seems like the database is already synchronized with the migrations. There are no problematic errors. (Although you shouldn't really be root to run the migrations.)
If you're looking into creating more migrations, use the south documentation, which usually is just running the following after you modify the models:
python manage.py schemamigration --auto <APP>
And then use python manage.py migrate to apply the changes.
It looks like migrations have been already passed. Check south_migationhistory table in db.
If you want to sync new db for apps which has migrations just disable south in settings.py.
Have you ran a schemamigration initial yet?
./manage.py schemamigration deals --initial
./manage.py migrate deals
if you get the error, db already excists do this:
./manage.py schemamigration deals --initial
./manage.py migrate deals --fake

south django migrate

I just did:
python manage.py schemamigration TestDBapp1 --initial
python manage.py schemamigration TestDBapp1 --auto
Successfully.
But if I enter: python manage.py migrate TestDBapp1
I get this: sqlite3.OperationalError: table "TestDBapp1_xyz" already exists
What could be the problem?
I suspect that you already executed syncdb which created the tables. South tries to create them again during migrate and naturally the database complains.
To avoid this you have to tell South to "fake" the initial migration.
python manage.py migrate TestDBapp1 --fake
As the name indicates this pretends to migrate. Note that this is an one time step. South will handle your future syncdb and migrate without requiring --fake.