Accidentally deleted my django south migration directory - django

I accidentally deleted the South migrations directory for one of my Django apps. This directory was not under git.
So now there are migrations in the database that are not present on the disk.
Some pointers on how I can recover from this will be much appreciated.

Without the option of any type of backup or finding the files somewhere, what you're going to have to do is make initial migrations and then fake them.
$ ./manage.py schemamigration app --initial
$ ./manage.py migrate app --fake
This will get you to where you are currently, however you won't have the option to migrate backwards.

Related

Django - Make migration command detects changes but on migrating says 'No migrations to apply'

i am new to django developement after making changes to my model i tried to run the command python manage.py makemigrations my_app
it detects changes in my model and shows me the message
todoapp/migrations/0001_initial.py
- Create model confess
- Create model UserChoice
- Create model comment
but on executing python manage.py migrate my_appcommand i've got this message
No migrations to apply.
i usually do this after making changes in models, i don't know what happened now.
plss help me.
Firstly, try
python manage.py makemigrations my_app
python manage.py migrate
If this does not work and the project is still in development:
Delete migrations folder and pycache folder.
Delete db.sqlite3 (your database).
Make and apply migrations again.
I think this will work.
Delete all migrations files and __pychache__except__init__.py from your project and app. Also db.sqlite3 database then rerun makemigrations and migrate commands. It should solve your issue.

Is it possible to make migrations from db not from model?

Suppose, we have a db's backup and a django program. The program do not have any migrations. First we restore db, that has created table and data. Now we want to make migrations from available db. Is it possible or not?
Yes, Django has the inspectdb method, which is described here.
But if the Django app already has the models defined that correspond to the backed up database, then you can just run makemigrations (follow #Shafikur's instructions).
Just go to your corresponding database terminals and delete all the records from you django_migrations table with
delete from django_migrations;
Go to terminal and run remove all files in migrations folder with
rm -rf <app>/migrations/
Reset all the migrations of the Django's built-in apps like admin with the command
python manage.py migrate --fake
Create initial migrations for each and every app:
python manage.py makemigrations <app>
To create initial fake migrations just run
python manage.py migrate --fake-initial

django, squash migrations, too many circular dependencies

I tried to squash migrations.
Unfortunately there are just too many circular dependencies.
Is there a way to start over the migrations (although my project is already deployed in production) than trying to squash the migrations?
I don't have to worry about some unknown developer using my project because it's a private project.
Yes, there is a way. See this similar question. In a nusthell:
# 1) Fake migrations back to 0
./manage.py migrate app zero --fake
# 2) Delete migrations files
git rm "app/migrations/*"
# 3) Create new migration file
./manage.py makemigrations app
# 4) Pretend to run the new migration
./manage.py migrate app --fake

Resetting migrations in south leads to 'table already exists'

OK, this is driving me nuts. I'm trying to remove and reset all my south migrations in my DEV environment for two apps, and start again with a clean slate, as my migrations files list was getting very long and I don't need them, as the models are constantly changing, and it's just DEV. Whatever I try, South constantly complains that the DB tables are already there.
Going on this answer on SO, I first remove my migrations dir entirely from each app:
rm -r <my-app>/migrations
No problem. Then reset the south tables:
python manage.py reset south
Again, no worries.
Now tell south that I want those apps managed:
python manage.py convert_to_south <appname>
All seems fine, it even creates the initial migration and runs the --fake:
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate CC
- Soft matched migration 0001 to 0001_initial.
Running migrations for CC:
- Migrating forwards to 0001_initial.
> CC:0001_initial
(faked)
OK, so according to my (incorrect) understanding, I now have my existing tables managed by south. South knows that the tables ALREADY exist, as we ran initial as --fake.
Now I add a new field to a model, run schemamigration then migrate on that new schema, and guess what, South complains that the tables already exist.
django.db.utils.DatabaseError: table "_south_new_CC_coveredcall" already exists
What the hell? What on earth am I doing wrong?
Caveat: it's late here and I'm tired, but it will be something along these lines:
Rather than telling South that you want to migrate an existing app (which implies a schema exists), you can fake-zero the apps, delete the migrations and make a new intitial one for each app and fake apply it. That basically gets South to replace multiple migrations with one per app
$ ./manage.py dumpdata myapp1 myapp2 > dumped.json # just in case!
$ ./manage.py migrate myapp1 zero --fake
$ ./manage.py migrate myapp2 zero --fake
$ rm /path/to/myapp1/migrations/.py*
$ rm /path/to/myapp2/migrations/.py*
$ ./manage.py schemamigration myapp1 --initial
$ ./manage.py schemamigration myapp2 --initial
$ ./manage.py migrate myapp1 --fake
$ ./manage.py migrate myapp2 --fake
The new 0001 migrations for myapp1 and myapp2 will have the same result as the multiple ones that actually created the existing schema, so all will fit just fine (as long as there have been no custom SQL migrations etc)
Try this code:
rm <app>/migrations/*
python manage.py schemamigration <app> --initial
python manage.py migrate <app> 0001 --fake --delete-ghost-migrations
Thanks to all who contributed - it turns out that as I'm using SQlite in dev, It's this that is causing all the issues. See another question on SO for clarification. Answering my own question here as it may be useful for others - I'm switching to mySQL, as the issue I stated above doesnt exist in my PRD env, which uses mySQL. Migration all works seamlessly.

Django - Deploy syncdb & South

I'm deploying a project on a new development environment.
As I'm using South I did:
$ python manage.py syncdb --all
$ python manage.py migrate --fake
I used syncdb --all to apply actual state of models.
Then migrate --fake to mark all models as migrated.
But after that, my model is not on the last version (missing fields)
What am I doing wrong ?
I assume all my modifications have migrations.
If I do
$ python manage.py syncdb
It seems to create the first state since when I used South (that is expected)
But then
$ python manage.py migrate
Some tables appears as already created
Actually this, should have been fine for my case
$ python manage.py syncdb --all
$ python manage.py migrate --fake
Having to redeploy my app recently, I faced the same issue.
I just realized that I had a double initial migration on the model that were causing the problem
0001_initial.py
0002_initial.py
0003_auto__add_field_mytable_myfield.py
I simply deleted & renamed
0001_initial.py
0002_auto__add_field_mytable_myfield.py
Then redone the whole database deployment (obviously not forgetting to update the already applied migrations on my other hosts)
--fake option does not avoid errors while trying to create new migrations. It records that migrations have applied without actually applying them.
Also, you need --ignore-ghost-migrations or --delete-ghost-migrations to achieve what you are looking for.
To convert an existing project to south, you first need to convert the app
Now, if you have already run --fake, to recover, you can do this:
Go to ./manage.py dbshell
DELETE FROM south_migrationhistory WHERE id > 0; //Note that this would delete everything in the table.
If you want to remove migrations of a specific app,
DELETE FROM south_migrationhistory WHERE app_name = 'blah'