Django migrate getting OperationalError - django

I'm fairly new to Django, I am using 1.10 version. I reached a point where I was unable to migrate because of an error, and so backed up to an earlier migration using ./manage.py migrate myapp 0003_auto_20160426_2022 and deleted the later migration files. I then repaired my models.py and ran makemigrations, which worked fine. But when I attempted to migrate, I received the following error (only showing last few lines)
File
"/Users/wahhab/Sites/rts/env/lib/python3.5/site-packages/MySQLdb/connections.py",
line 280, in query
_mysql.connection.query(self, query) django.db.utils.OperationalError: (1022, "Can't write; duplicate key in table '#sql-72_4a6'")
I don't know how to move forward from this point so that I can continue working on my project. I have data in other apps but only a little test data in this new app so far, so I have considered deleting all migrations and the MySQL tables for this app and starting over, but I don't want to create a worse mess than I have and don't know what is causing this error. Any advice is welcome. Thanks!

Okay so a hackish solution has already been suggested by #raratiru.
Now the explanation for WHY you were facing the above problem is that when you deleted you migrations, Django resets all its counters, which also includes the counter of the key, but because the deletion of migrations was a manual one, the data still persists in your DB.
So there already exists objects in your DB with key = 1, 2, 3 ....and so on. But Django doesn't know this and hence when you have deleted just the migrations and not the data, Django faces a clash of key as Django again starts assigning automatic key values from 1, which already exists in the DB. But as the key needs to be unique, it gives you an error.
Hence if you delete both the migrations and the data, you don't get thee error.

Related

Django migrations integrity error column contains null values

django.db.utils.IntegrityError: column "required_tem_grid" contains null values
So I mistakenly gave wrong type of value when Django asked me to provide default value for existing rows. Problem is now that I am stuck with this error. I have been burned by this error before too and the only way I could recover was to create another db and running migrations again. Is there any other way? I have tried to revert to previous migration (initial) but this error pops up everywhere. There is no such column in the database that I can see. Is there some place this default value gets cached?
Well I managed to solve it this way: Delete migration files and cached files, remove offending entry from models, delete migration data from django_migrations table for the app, run makemigrations and migrate --fake-initial. I was then able to change models and run migrations.

Load fixtures + add Page: IntegrityError (duplicate key value)

I have a migration that loads a fixture for populating the database with a basic site structure (from Loading initial data with Django 1.7 and data migrations
). After that migration ran, my test adds a (custom) NewsPage. THis yields an "IntegrityError at /admin/pages/add/website/newspage/5/
duplicate key value violates unique constraint "wagtailcore_page_pkey"
DETAIL: Key (id)=(3) already exists." The same happens when i add the page through the admin interface.
It's a bit suspicious that the Page with pk=3 is the first one that is created in my fixture. The other two pk's were already created by Wagtail's migrations.
I've read up about fixtures an migrations, and it seems Postgres won't reset the primary key sequences. I'm assuming this is also my problem here.
I found a possible solution in Django: loaddata in migrations errors, but that failed (with "psycopg2.ProgrammingError: syntax error at or near "LINE 1: BEGIN;"). Trying to execute the gist of it, I ran the sqlsequencereset management command (./manage.py sqlsequencereset wagtailcore myapp), but i still get the error, although now for id=4.
Is my assumption correct that Postgres not resetting the primary key sequences is my problem here?
Does anyone know how to reliably fix that from/after a migration loaded fixtures?
Would it maybe be easier / more reliable to create content in Python code?
Edit (same day):
If i don't follow the example in Loading initial data with Django 1.7 and data migrations, but just run the management command, it works:
def load_fixture(fixture_file):
"""Load a fixture."""
commands = StringIO()
call_command('loaddata', fixture_file, stdout=commands)
I don't know what the drawbacks of this more simple approach are.
Edit 2 (also same day):
Ok i do know, the fixtures will be based on the current model state, not the state that the migration is for, so it will likely break if your model changes.
I converted the whole thing to Python code. That works and will likely keep working. Today i learned: don't load fixtures in migrations. (Pity, it would have been a nice shortcut.)

Django won't create a table

I have two different databases in django. Initially, I had a table called cdr in my secondary database. I decided to get rid of the second database and just add the cdr table to the first database.
I deleted references (all of them, I think) to the secondary database in the settings file and throughout my app. I deleted all of the migration files and ran make migrations fresh.
The table that used to be in the secondary database is not created when I run migrate even though it doesn't exist on my postgres database.
I simply cannot for the life of me understand why the makemigrations function will create the migration file for the table when I add it back in to the model definition and I have verified that it is in the migration file. When I run migrate, it tells me there are no migrations to apply.
Why is this so. I have confirmed that I have managed=True. I have confirmed that the model is not on my postgres database by logging into the first database and running \dt.
Why does Django still think that this table still exists such that it is telling me no migrations to apply even though it shows a create command in the migrations file? I even dropped the secondary database to make sure it wasn't somehow being referenced.
I suspect code isn't needed to explain this to me but I will post if needed. I figure I am missing something simple here.
Why does Django still think that this database still exists such that
it is telling me no migrations to apply even though it shows a create
command in the migrations file
Because django maintains a table called django_migrations in your database which lists all the migrations that have been applied. Since you are almost starting afresh, clear out this table and then run the migrations.
If this still doesn't work and still assuming that you are still on a fresh start, it's a simple matter to drop all the tables (or even the database and do the migration again). OTH that you have data you want to save, you need to look at the --fake and --fake-initial options to migrate

Fixtures causing problems when migrating

One of my apps has an initial_data.json file in /fixtures, which works great when using vanilla django to specify some initial data. However, when migrating using South, when it steps through 'Loading initial data for ' I get an IntegrityError, because duplicate data already exists. This makes sense, because my migration didn't empty the table, so the initial data from previous calls to syncdb is already there.
How can I either 1) tell South to not load initial data while migrating, or 2) modify initial_data.json or other django files so that duplicate data errors are handled gracefully, instead of crashing the migrate process in south?
migrate using the --no-initial-data option

Django: flush command doesnt completely clear database, reset fails

I rewrote a lot of my models, and since I am just running a test server, I do ./manage.py reset myapp to reset the db tables and everything has been working fine.
But I tried to do it this time, and I get an error,
"The full error: contraint owner_id_refs_id_9036cedd" of relation "myapp_tagger" does not exist"
So I figured I would just nuke the whole site and start fresh. So i did ./manage.py flush then did a syncdb this did not raise an error and deleted all my data, however it did not update the database since when I try to access any of my_app's objects, i get a column not found error. I thought that flush was supposed to drop all tables. The syncdb said that no fixtures were added.
I assume the error is related to the fact that I changed the tagger model to having a foreignkey with a name owner tied to another object.
I have tried adding related_name to the foreignkey arguments and nothing seems to be working.
I thought that flush was supposed to drop all tables.
No. According to the documentation, manage.py flush doesn't drop the tables. Instead it does the following:
Returns the database to the state it was in immediately after syncdb was executed. This means that all data will be removed from the database, any post-synchronization handlers will be re-executed, and the initial_data fixture will be re-installed.
As stated in chapter 10 of The Django Book in the "Making Changes to a Database Schema" section,
syncdb merely creates tables that don't yet exist in your database — it does not sync changes in models or perform deletions of models. If you add or change a model's field, or if you delete a model, you’ll need to make the change in your database manually.
Therefore, to solve your problem you will need to either:
Delete the database and reissue manage.py syncdb. This is the process that I use when I'm still developing the database schema. I use an initial_data fixture to install some test data, which also needs to be updated when the database schema changes.
Manually issue the SQL commands to modify your database schema.
Use South.