How is one supposed to recover from a failed migration in South? - django

I'm using South (version 0.6, the one packaged in Ubuntu Lucid Lynx) to manage database migrations in Django, and currently using SQLite as a back end. I came across a situation where I generated a migration to add a column with:
./manage.py startmigration myapp --auto added_new_column
... which generated a migration that looked sensible. However, when I then applied the migration with:
./manage.py migrate myapp
I got an error because the column I was adding was non-NULL, but I hadn't specified a default value:
ValueError: You cannot add a null=False column without a default value.
What is one supposed to do if a migration fails in this way, and you want to go back and regenerate it? (What I did in practice, namely to delete the migration and generate a new one, has created several further problems.) Perhaps I've missed something obvious in the documentation about this...

In this case, migration failed and didn't get written into db, so you can safely remove old one and create again. Also you can try using newer south version, i believe they added default check for NOT NULL fields on creating step.

Related

Django migrate didn’t launch execute some migration files

I have a Postgres database full of data. And I made several changes to my Django app models.
mange.py makemigrations worked fine and created the migration files. But manage.py migrate execute only one file. And when I launch it again it doesn’t execute the rest as if they are already applied.
I deleted the migration files that were not applied and did another makemigration but it says no changes detected.
Any ideas how to reflect the models changes on the database without losing the data ?
Thanks
Django keeps track of which migrations it has applied already, so when you run the migrate command it will execute only the migrations that Django thinks that are missing.
I deleted the migration files that were not applied and did another makemigration but it says no changes detected.
This was a bad idea, it will make your migrations inconsistent.
If you want to go back in time, instead of deleting migrations, the proper way to do this is by reverting migrations. You can use the same migrate command and specify to which migration point you want your database model to be.
Check this answer for further information about reverting migrations; django revert last migration

Django migrations, resolving merging problems

As I was changing my models.py and migrating, I got an error message saying:
python manage.py makemigrations project_profile
CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0033_auto_20180217_0912, 0036_auto_20180217_0927 in project_profile).
To fix them run 'python manage.py makemigrations --merge'
So, when I tried to follow the instructions, I got another error that one of my tables that the merged migration is now depending on do not exist anymore (I renamed it). Interestingly enough, this renaming took place during the merge operation. So, really Django should have known about it in the first place.
To resolve the situation, I deleted prior migrations up to and including the migrations that was not applied, the one that caused all the headache. I tried to makemigrations and migrate again. But, Django now throws another error saying some of the models it wants to create in the database already exist. Obviously, I do not want to delete those tables and loose all that information to appease Django. So, I had to resort to some hacking solutions and actually change those tables manually and do a fake migration in order to stop Django from complaining.
Having said all of that, I feel like there should be a more logical way about this. How do I resolve migrations during the merging?
I had the same issue, Then I was able to solve this by deleting the migrations file that django pointed out and starts with name auto. It occurred 2-3 times before it finally gave up and finally worked.
Alternatively you can django-dbbackup or django-import-export packages to backup the tables then clean your database and migrations. Then you can restore them back to the same state once migrations are stable.
Sources
dbbackup : https://django-dbbackup.readthedocs.io/en/stable/
import-export : https://django-import-export.readthedocs.io/en/latest/index.html

IntegrityError: Not Null constraint failed

I have deleted a class from model.py but whenever I run python manage.py migrate, I get this:
intergrityerror : not null constraint failed: appname_modelclassfieldname.user_id
The most challenging thing is that I had already deleted the model class of the related field django is pointing error at.
You have to create a migration before running migrate. As you have not specified your Django version, here is what you need to do for the most recent version (1.11) which also works down to at least 1.9:
$ ./manage.py makemigrations # > creates a migration file
$ ./manage.py migrate
You can specify the the app in the makemigrations call if you want.
Concerning:
The most challenging thing is that i had already deleted the model class of the related field django is pointing error at .
Use a version system for your own health (e.g. GIT) or an editor that supports local versioning (like PyCharm) - best use both - even if you are working alone. (You are never alone, after some weeks, the code looks like it was written by someone else...)
The problem was an error with the server .I had delete the app and create a new one ,and everything is working just fine now

What is the correct way to deal with migrations of Django Database when pushing files to the remote git repository?

Actually we are group of 3 people working on the same project, and each one individually make changes in django database. After running migrations in individual machine, it creates migration file for each migration. When someone pushes updated code in remote git repository, it creates conflict with others' migrations of same name.
Because of this reason, I lost my whole data once. Kindly give suggestions what should I do with this migration thing?
here's what i do: whenever I want to fetch from remote i check if a duplicate migration will be fetched. (we have a script that checks for all migration directories if there are filenames which have the same starting number.) if that is the case, I 'merge' the migrations, usually like this:
Find the last migration before the duplicate, let's say it's migration 000X
Make sure you are on your local source version, before the duplicate is added.
migrate back to after migration n:
python manage migrate app 000X
pull the new version including the duplicates.
remove your duplicate migrations
run schemamigration
python manage schemamigration --auto
Now you should get a new migration adding your model changes on top of the changes that were made in the migration you pulled.

how to change the order of south migrations

I have around fifty migrations in my store app, some of them are schemamigration and some datamigration. Now i want to run 0039_add_column_is_worldwide before 0037_some_values_to_objects. So I changed there name 0037_add_column_is_worldwide and 0039_some_values_to_objects.
It works fine when i did syncdb for new db but while migrating for a new migration in existing db it gives this error.
raise exceptions.InconsistentMigrationHistory(problems)
south.exceptions.InconsistentMigrationHistory: Inconsistent migration history
The following options are available:
--merge: will just attempt the migration ignoring any potential dependency conflicts.
I didn't want to lose my data, so is there anyway to change the order of these migrations?
Migration are stored in DB when ran, so if you already applied these migrations south is going to get lost. Your alternatives:
flush the migration table (will cause all migration to run again if you call migrate)
rollback these migrations (before renaming)
fake these migrations (migrate --fake, but the numbers may conflict with the one in DB anyway)
Rollback seems the safest to me, just be sure everybody in your project do the same.
If you are still in dev and you have no prod database, you can always restart from zero:
flush the south db
migrate --fake
I guess your database has already done "0037_some_values_to_objects".
I would do it like this:
Remove the code inside the forward() and other method in "0037_some_values_to_objects". This migration does nothing. Now add two new migrations.
Rule of thumb: If one system has done a migration, don't delete it. Make it empty.