Django South migrations after migrate starts from initial - python

I added field to my model in banks app, run python manage.py schemamigration banks --auto which generates correct migration but after migrate, don't know why South start over from initial migration.
python manage.py migrate banks
Running migrations for banks:
- Migrating forwards to 0038_auto__add_field_offer_description.
> banks:0001_initial
FATAL ERROR - The following SQL query failed: CREATE TABLE `banks_lendingtarget` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(255) NOT NULL UNIQUE)
The error was: (1050, "Table 'banks_lendingtarget' already exists")
Even if I start migrate with specified migration name like:
python manage.py migrate banks 0038_auto__add_field_offer_description
There is the same error, and my question is: why?
I was thinking that recently added initial_data.json to my app can cause this but after renaming it nothing changes. Have anyone of You have same situation? Thanks for help.

This is assuming you are using South 0.8 or so and Django 1.6 or below:
I can't explain why this happened without knowing more about the history of your database and South usage, but to help in diagnosing the issue you could manually inspect the South migration history table in your database.
However, whatever you find out, the remedy is likely to be the same: you can "fake" the migration and skip ahead to the proper place in your migration history.
Try python manage.py migrate banks 0037 --fake. That will take you to just BEFORE the 0038 migration without actually trying to create tables. Of course, this assumes that 0037 is the most recent migration that was successfully applied to your database.

Related

django-safedelete 1.3.0 - Cannot migrate

I built an internal app that used django-safedelete. I was working fine for months, until i recently upgraded my distro, and tried to add a field to my model.
I also upgraded my python modules, everything is up-to-date, and no errors during the upgrade.
Now I cannot migrate anymore:
if I "makemigrations" I get an error message "django.db.utils.OperationalError: (1054, "Unknown column 'gestion_ltqmappsetting.deleted_by_cascade' in 'field list'")"
if I add a boolean "deleted_by_cascade" field in my ltqmappsetting table, then the "makemigration" works, but the "migrate" fails with "MySQLdb.OperationalError: (1060, "Duplicate column name 'deleted_by_cascade'")"
I tried removing the field after makemigrations, but the migrate fails with the first error message.
I also tried removing the "migration" operations in the 0087...migration.py file, but it does not have any impact.
Is there anyway to update the migration file between the makemigrations and the migrate commands ?
Thanks a lot for any help on this.
jm
It's a wonder how I can actually look for answers for hours, then post on this site, and a few minutes later, I actually find the answer ...
Anyway.
It looked like I was mistaken on the meaning of the second error message. It failed because a previous migration already create the deleted_by_cascade field in another table, not in the appsetting one.
So the steps to solve my issue where:
migrate migrate 0086 to remove the latest migrations
make sure the DB only had the deleted_by_cascade column in the appsetting table
makemigrations - this creates the 0087 migration to add deleted_by_cascade column in all tables
edit the 0087 migration to not create the new column in the appsetting table
run makemigrations once again - - this creates the 0088 migration to add deleted_by_cascade column in the appsetting table
migrate 0087
migrate --fake 0088
Et voila ...
There was probably something wrong in the safe_delete update.
Hope this can help others.
jm

python manage.py migrate landing error

I want to migrate my app "landing" with south I write the following command
python manage.py migrate landing
but it shows the following error
Running migrations for landing:
Migrating forwards to 0003_auto__chg_field_userinput_email2.
landing:0001_initial
FATAL ERROR - The following SQL query failed: CREATE TABLE landing_userinput (
id integer AUTO_INCREMENT NOT NULL PRIMARY KEY, name varchar(120) NOT NULL,
email varchar(200) NOT NULL, city varchar(120) NOT NULL, timestamp datetim
e NOT NULL)
The error was: (1050, "Table 'landing_userinput' already exists")
! Error found during real run of migration! Aborting.
! Since you have a database that does not support running
! schema-altering statements in transactions, we have had
! to leave it in an interim state between migrations.
! You might be able to recover with: = DROP TABLE landing_userinput CASCAD
E; []
raise errorclass, errorvalue
django.db.utils.OperationalError: (1050, "Table 'landing_userinput' already exists")
Please give me suggestions to improve this bug.
Don't use syncdb and migrate at the same time; this will conflict as the initial migration will create a blank table.
If you have a new app and want to have it managed by south, your sequence of operations is:
./manage.py schemamigration landing --initial -- this creates the initial migration, which creates the tables for the application. You only do this once.
./manage.py migrate landing -- this will apply the migration. The first time you do this (with step #1 from above), this will create an empty table in the database.
Once you have done the first two steps, whenever you make a change to your model, you run these two commands:
./manage.py schemamigration landing --auto -- this will create the file that has the changes to your model (the migration).
./manage.py migrate landing -- this will apply the new migration (this is the same command from above); and it will affect the changes to your database.
If you already have an existing application, install south and run syncdb to create south's own database tables, then run ./manage.py convert_to_south yourappname; this will do a "fake" migration and set it to the last state of the models. Then, follow the schemamigration yourappname --auto and migrate steps.
In your case, you have two options:
Drop the table (as the error suggests). This will get rid of all the data as well. If you are in development, this is the easiest way to get started fresh (you should also use fixtures if you want to provide some default data for your models).
You can use the --fake option to trick south into thinking the operation has been done already. See the documentation for more.

Recovering from a duplicate migration in Django South

Due to merging several feature branches into my project, I have the following migrations:
0001_initial.py
0002_auto__add_field_userprofile_telephone__add_field_userprofile_timezone.py
0003_auto.py
0004_auto__del_field_organisation_admin.py
0005_auto__add_field_organisation_permitted_domains.py
0005_auto__add_field_userprofile_currency.py
Note that I have two duplicate 0005 migrations. These ran fine, and deployed fine on my production system.
$ python manage.py migrate accounts --list [17:11:42]
accounts
(*) 0001_initial
(*) 0002_auto__add_field_userprofile_telephone__add_field_userprofile_timezone
(*) 0003_auto
(*) 0004_auto__del_field_organisation_admin
(*) 0005_auto__add_field_organisation_permitted_domains
(*) 0005_auto__add_field_userprofile_currency
My table has the correct columns:
$ psql
db_my_project=# \d+ accounts_organisation
db_my_project=# \d+ accounts_userprofile
... shows currency and permitted_domain, suggesting the migrations worked correctly
However, if I try to create a new migration, South thinks that I haven't added the column' permitted_domains' to my model:
$ python manage.py schemamigration accounts --auto [17:16:15]
+ Added field permitted_domains on accounts.Organisation
Created 0006_auto__add_field_organisation_permitted_domains.py. You can now apply this migration with: ./manage.py migrate accounts
How do I fix this?
From the docs: http://south.readthedocs.org/en/0.7.6/autodetector.html
When the autodetector runs, it compares your current models with those
frozen in your most recent migration on the app, and if it finds any
changes, yields one or more Actions to the South
migration-file-writer.
The migrations keep a frozen version of the fields within the model in a dict.
Therefore:
In 0005_auto__add_field_organisation_permitted_domains the Organisation class will have a field permitted_domains but in 0005_auto__add_field_userprofile_currency it will not. When you run:
$ python manage.py schemamigrate accounts --auto
this will compare the current state of the code against the record of the fields store in 0005_auto_add_field_userprofile_currency, thus leading south to add the field for a second time.
If you copy the line for the 'permitted_domains' field from 0005_auto__add_field_organisation_permitted_domains to 0005_auto__add_field_userprofile_currency this will solve your problem.
It is a very specific problem, I hope this helps, do the following:
1) Rename this file: 0005_auto__add_field_organisation_permitted_domains to 0006_auto__add_field_organisation_permitted_domains
2) Rename the number of your recently migration file from 0006 to 0007
3) Issue the command python manage.py migrate account 0006 --fake to deceive south.
4) Issue the command python manage.py migrate account 0007
That might get the south engine in sycn again with your application
Hope this helps!

How to run test with migrate appname --fake?

My test not working. If I try python manage.py test appname I have this error:
! You *might* be able to recover with: = DROP TABLE "appname_userprofile"; []
= DROP TABLE "appname_table2"; []
= DROP TABLE "appname_table3"; []
! The South developers regret this has happened, and would
! like to gently persuade you to consider a slightly
! easier-to-deal-with DBMS (one that supports DDL transactions)
! NOTE: The error which caused the migration to fail is further up.
Error in migration: content:0015_initial
django.db.utils.DatabaseError: table "appname_userprofile" already exists
How to run my python manage.py test appname with
manage.py migrate appname --fake
You'd have to write a custom test runner to selectively add --fake to individual migrations, as far as I know.
You should probably fix your database migrations -- it looks like you have two migrations which are trying to create the same table.
South wants to run all of your migrations, in order, before starting the tests, in order to build up an initial database, and right now it can't do that.
You can disable South completely for unit tests if you put this in your settings.py file (reference):
SOUTH_TESTS_MIGRATE = False
If you do that, then the Django test runner will just create your test database based on your current models, rather than running migrations to build it.

You cannot add a null=False column without a default value

I'm adding a new app, and while setting up the database using South I get the following:
... line 11, in forwards
db.add_column('experiments_dailyreport', 'test_group_size',
orm['experiments.dailyreport:test_group_size'])
You cannot add a null=False column without a default value.
Given that this is a new table with no data in it, is there some way to force this migration?
You can force a migration using:
manage.py migrate --fake django-lean 0005
where 0005 is the version number of the migration. All that matters in your situation are:
having the correct database schema in the end
having South think that all migrations have been run
After that you can run the other migrations as normal. Alternatively, you can remove South, create the latest tables from django-lean using syncdb and then fake all the django-lean migrations.
Lastly, if you're certain that there's something wrong with the migration, it's worth contacting the django-lean developer(s) about this.

Categories