Django InconsistentMigrationHistory when adding app initial migration - django

[edit] solution found, details below
There are some interesting suggestions in a similar question but it doesn't help with my problem. Also, I have this app in production in several countries.
We are migrating an app and started with managed=False on all models. We then had a claim_batch app that has a migration 0002_capitationpayment:
dependencies = [
('product', '__first__'),
('claim_batch', '0001_initial'),
]
# Some models with foreign keys to "product.Product"
The product module doesn't have migrations but it has models. When I do a showmigrations in this situation, I have:
product
(no migrations)
And it works fine somehow.
The problem is that I now need to add migration with a managed table in product. When I do the makemigrations and try to migrate, I'm getting:
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration claim_batch.0002_capitationpayment is applied before its dependency product.0001_initial on database 'default'.
It makes sense. The claim_batch.0002 is referencing a migration that is now existing but was not applied and it should not be possible to apply it after its dependency. Except in this scenario.
If I try to remove the dependency from the already applied migration, I'm getting:
ValueError: The field claim_batch.CapitationPayment.product was declared with a lazy reference to 'product.product', but app 'product' isn't installed.
I'm guessing that a clean install with this would work fine but I have production systems in various countries running in this state. Starting from scratch is not really an option.
[EDIT]
I can get it to work by manually adding the initial migration of the product app into the django_migrations table. It's not the best solution but it's manageable.

Related

Initial migrations after cloning repo - "related model cannot be resolved"

I'm working with a few people on an app. I'm doing front end.
Recently, I've messed up migrations. After trying to fix them for a few hours, I've dropped all tables, and cloned the repo again.
Since there are no migrations files, I run manage.py makemigrations (for some reason it does not detect all apps, just one of them, and I have to call makemigrations manually for each of them).
Then, I run manage.py migrate. I get the following error:
Related model 'User.user' cannot be resolved
Since User table has OneToOneField relation to User table. Also, other tables depend on each other as well.
My take on this problem would be commening out all the fields that cause the problem, making migrations, uncommenting them, and making migrations again.
How should I fix it?
Ok, I solved this particular problem:
In User app there was another model, which referred to User. Automatically created migration file had this model before User model, so the script failed, since it could not refer to a model that is yet not created.
I solved this by editing the migration file, swapping the order of creating models - so the second model can refer to the first one.

How to make the initial migration for a DB that diverged from the corresponding models?

Situation: a project I'm working in had a file corruption or something. Models are the latest version, but the SQLite DB had to be rolled back before some columns were added/removed/modified. Migration files are all gone. Trying to create migrations anew results in the new columns being present in the initial migration file, so I can neither migrate for real (due to the table existing) nor fake it (since the columns are missing in the DB).
Given those circumstances, how can I make an initial migration matching the columns currently present in the DB so I can fake it and then make a real second migration to bring the tables in line with the models? The only thing that comes to mind is manually tweaking the models to match the DB schema, making the initial migration, faking it and then restoring the new version of the models, but I'd much prefer having this done automatically.
django inpsectdb to the rescue.
But first, learn how to use git if you had used proper version control, you would not be facing this difficulty now.
First step, add the code to version control.
Delete the existing models files
Use inspectdb to generate a models.py from the tables in the database. This is not perfect, you will have to edit the file manually and you may have to spread it out between different models files manually.
Now delete the contents of the migrations table
do a ./manage.py makemigrations (yourapp)
Do the fake migration you mentioned
replace the generated models.py with your current models.py (a git checkout of that file will do the trick nicely)
do a makemigrations and migrate again.
good luck.

Django: Removing unique constraint and creating migration

I have created a model and migrated in Django, with a unique key constraint for one of the field. Now am trying to remove the unique constraint and generate another migration file with the new change, but it says "Nothing seems to have changed".
I tried with the command
python manage.py schemamigration --auto
PS: I am using OnetoOne relationship for the field.
Good question. A one to one relationship implies that one record is associated with another record uniquely. Even though the unique constraint is removed(for one to one field) in the code explicitly, it won't be reflected in your DB. So it won't create any migration file.
If you try the same thing for foreign constraint, it will work.
I find the django automigration file generation problematic and incomplete.
Actually I experienced another similar problem with django migration just yesterday.
How I solved it:
delete all migration files from the /migrations folder
do a fresh makemigrations
run python manage.py migrate --fake so django does not try to rebuild..
Hey presto! Working and models updated :D

Added a field to a model, how do I update the database to changes to the model

All I did was add a field to a model, and now I get an error that says this column does not exist.
In an attempt to rebuild the database I used -flush (i dont care about losing the data), thinking this would rebuild the database, but I still get the same error.
I was told by someone else to use South because I'm running Django 1.6.
I followed the tutorial and literally the first time I ran syncdb, I got the following (probably unrelated) error:
dist-packages/easy-thumbnails/
raise Improperly_Configured(SOUTH_ERROR_MESSAGE)
django.core.exceptions.ImproperlyConfigured:
For South Support, customize the SOUTH_MIGRATION_MODULES setting like so:
South_Migration_Module = {
'easy_thumbnails': 'easy_thumbnails.south_migrations',
}
Ultimately all I want to do is have my db reflect my models. Back when I was working on this project in my dev environment I would literally just drag my sqlite file to the trash and then run syncdb, but I cannot do that now because I'm using postgres.
So my question is how can I accomplish this seemingly simple task? Whether that means addressing the South error, or just not using South altogether (which I would prefer), I would appreciated any help.
You can manually open up a db shell (>>> python manage.py dbshell) and drop the table with DROP TABLE <table_name>;. In order for syncdb to recreate a table with the new field, it is not enough to empty the table.
To solve the error, just do exactly what it says: add the SOUTH_MIGRATION_MODULES setting to your settings.
With that said, I'd definitely advice you to use south. It eases making changes to your models, and it allows you to preserve test data in your development environment that you'd otherwise have to recreate. That's all nice, but when your project goes live, it is absolutely mandatory that your data is preserved when making a change to your models. South is the best tool for that.
South has been such an integral part of pretty much any Django project, that Django has worked together with the developers of South to include it as a core feature from Django 1.7 onwards.

Generally, when does Django model change require South?

I am new to Django. I have completed the tutorial and am reading the documentation for more learning. As I try to add to my understanding, say, in new Managers or ModelForms I am curious as to what needs South (or even just scrapping it and rewriting the app).
update django database to reflect changes in existing models
The link above says basically that any column change it is necessary, while the link below is more of what I am asking. Can someone generalize when it is not needed (eg: Adding a new Form/ModelForm based on an existing Model? Adding a Manager?) If no changes are made to the columns of the database South is not then not necessary?
Does changing a django models related_name attribute require a south migration?
There are two types of south migrations: schema and data.
Data migrations are used to change data in the DB and not the schema of the DB.
The schema migrations are the ones you are interested in. They are used to keep track of changes to the DB schema and one should accompany any changes to your models that result in DB schema change (create table, drop table, drop column, change null constrain e.g.)
Some great insights might be found if you read two consecutive migrations for a django app.
In each of them you can find code that applies the migreation, code that reverts the migrations and a snapshot of the DB schema.
P.S. It is quite easy to check if south migration is needed for a particular change in your models. Just run a schemamigration for the modified django app and delete the newly created migration if such was created. As creating a south migration is different that running it, this is a great way to test and learn.
Keep in mind that south is a piece of software like any other and it does 'support' bugs.
Related_name attribute changes only affect your project and django uses it to make queries.
Changes like blank = True/False, null = True/False, symmetrical = True/False require database changes although symmetrical = True/False does not trigger update by south, but the setting definitely makes difference at field creation.
Column changes, like the link in your post shows, require updates in database and that's what south does very good.