How to handle exceptions in a Django migration? - python

How do I catch an exception in a Django migration?
I have a migration that, because of various legacy reasons, I expect to fail sometimes. I want to be able to catch that error and run some error handling code in that case.
Specifically, I'm renaming a table, and sometimes the destination table already exists and I want to merge the contents of the old and new tables, then delete the old one.
I'm running Django 1.7 ( :( ) and we're planning on upgrading to 1.8 but it hasn't happened yet.
My migration is:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0007_migration_name'),
]
operations = [
migrations.AlterModelTable(
name='table_name',
table='LegacyTableName',
),
]
When I run this, I get
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File ".../django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File ".../django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File ".../django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File ".../django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File ".../django/core/management/commands/migrate.py", line 161, in handle
executor.migrate(targets, plan, fake=options.get("fake", False))
File ".../django/db/migrations/executor.py", line 68, in migrate
self.apply_migration(migration, fake=fake)
File ".../django/db/migrations/executor.py", line 102, in apply_migration
migration.apply(project_state, schema_editor)
File ".../django/db/migrations/migration.py", line 108, in apply
operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
File ".../django/db/migrations/operations/models.py", line 236, in database_forwards
new_model._meta.db_table,
File ".../django/db/backends/schema.py", line 350, in alter_db_table
"new_table": self.quote_name(new_db_table),
File ".../django/db/backends/schema.py", line 111, in execute
cursor.execute(sql, params)
File ".../django/db/backends/utils.py", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File ".../django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File ".../django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File ".../django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File ".../django/db/backends/mysql/base.py", line 129, in execute
return self.cursor.execute(query, args)
File ".../MySQLdb/cursors.py", line 226, in execute
self.errorhandler(self, exc, value)
File ".../MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorvalue
django.db.utils.OperationalError: (1050, "Table 'LegacyTableName' already exists")
All that's provided in the migration itself is the operations list, and there doesn't seem to be an optional error-handling parameter in the docs.
How do I catch the OperationalError so I can run some Python to merge the tables?

The problem with trying to catch database exceptions in Python is that they may not be specific enough - e.g., OperationalError could arise for various reasons (only one of which is that the table name has already been changed).
I would suggest that rather than trying to catch exceptions you write your own migration function that does whatever checks/modifications are necessary. See the documentation on RunPython.
This is generally the operation you would use to create data migrations, run custom data updates and alterations, and anything else you need access to an ORM and/or Python code for.
In your case you would write a function that checks whether the table exists and performs some actions for either case.
There are some database-specific issues to be aware of when writing these functions, e.g., :
on PostgreSQL, for example, you should avoid combining schema changes and RunPython operations in the same migration or you may hit errors.

Related

Django unable to migrate PostgreSQL: constraint X of relation Y does not exist

I'm trying to run a Django 1.11 migration on a PostgreSQL 9.6.5 database, and I'm getting the odd error:
Applying myapp.0011_auto_20171130_1807...Traceback (most recent call last):
File "manage.py", line 9, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 204, in handle
fake_initial=fake_initial,
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 115, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 129, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/migrations/operations/models.py", line 536, in database_forwards
getattr(new_model._meta, self.option_name, set()),
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 349, in alter_unique_together
self._delete_composed_index(model, fields, {'unique': True}, self.sql_delete_unique)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 380, in _delete_composed_index
self.execute(self._delete_constraint_sql(sql, model, constraint_names[0]))
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 120, in execute
cursor.execute(sql, params)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/myproject/.env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: constraint "idx_32269_myapp_mymodel_title_333195ae82ac2107_uniq" of relation "myapp_mymodel" does not exist
The migration is changing a unique contract from including one column to two. Pretty simple. It needs to destroy the old index, "idx_32269_myapp_mymodel_title_333195ae82ac2107_uniq", before creating the new one. However, it fails because it doesn't think the old one exists.
So I connected to the database with pgAdminIII and inspected the table, and contrary to the error message, the table does have an index called idx_32269_myapp_mymodel_title_333195ae82ac2107_uniq.
I thought maybe Django is using slightly different connection parameters, and is connecting to a different database? Let's try inspecting it from inside a Django dbshell. So I started manage.py dbshell and ran:
SELECT *
FROM pg_stat_all_indexes
WHERE indexrelname='idx_32269_myapp_mymodel_title_333195ae82ac2107_uniq';
and it returned one row.
Why is Django unable to see this index during a migration, even though the index definitely exists in the database?
The problem turned out to be that I converted the database to PostgreSQL from MySQL using the tool pgloader, and this tool converts constraints by creating them as indexes in PostgreSQL, whereas the Django PG backend creates them as constraints. So when the migration runs, it only looks for constraints and doesn't find any.
I fixed this by dropping the index and re-creating it as a true constraint with:
DROP INDEX idx_32269_myapp_mymodel_title_333195ae82ac2107_uniq;
ALTER TABLE public.myapp_mymodel ADD CONSTRAINT idx_32269_myapp_mymodel_title_333195ae82ac2107_uniq UNIQUE(title);
After that, the Django migration ran correctly.

Django Make Migration Error No Such Column

I have a pre-existing model that I am now trying to add an additional field too. It wasn't me that made the original field but I have been adding fields to other classes and making migrations fine.
I want to add an additional image field to the class Event, there is already an image field on this class so I know it can handle image fields, I have tried changing the name around to see if that was a issue too. Here is the field I want to add:
social_media_image = models.ImageField(null=True, blank=True, help_text='Hello World')
This is the error I get when i'm trying to make my migration after adding that code to the model:
django.db.utils.OperationalError: no such column: posts_event.social_media_image
From my understanding of how migrations work there shouldn't be a column called this yet as I haven't made the migration yet that will add it to the DB.
I have tried adding a default value to the field as well but with no luck. I have also tried completely removing the DB along with migration files and trying to recreate them.
Here are the rest of the fields in the model:
slug = AutoSlugField(max_length=50, unique=True, populate_from='title')
content = models.TextField(default='')
start_time = models.DateTimeField()
image = models.ImageField(null=True, blank=True, help_text=image_help_text)
Here is the traceback:
Traceback (most recent call last):
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such column: posts_event.social_media_image
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 341, in execute
django.setup()
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/source/enfield_presents/posts/apps.py", line 37, in ready
search.register(Event.objects.get_upcoming_events(site_id=settings.SITE_ID, include_spektrix=False, return_queryset=True))
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/source/enfield_presents/posts/models.py", line 282, in get_upcoming_events
events_with_a_next_start_time = [e for e in events if e.next_start_time() is not None]
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/models/query.py", line 256, in __iter__
self._fetch_all()
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/models/query.py", line 1087, in _fetch_all
self._result_cache = list(self.iterator())
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/models/query.py", line 54, in __iter__
results = compiler.execute_sql()
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/models/sql/compiler.py", line 835, in execute_sql
cursor.execute(sql, params)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/venv/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such column: posts_event.social_media_image
This issue may be due to the reason that the corresponding Image field may not be present in the database. Please login to the database shell and check whether the corresponding field is there. If it is not there add it manually using SQL query or rollback to a previous safe migration and then make the changes in models.py and generate the migration files.
It's right there:
File "/Applications/XAMPP/xamppfiles/htdocs/enfield/enfield-presents/source/enfield_presents/posts/apps.py", line 37, in ready:
search.register(Event.objects.get_upcoming_events(site_id=settings.SITE_ID, include_spektrix=False, return_queryset=True))
You do a queryset on the source of one app, that as far as I can tell, queries the model of the other app. You shouldn't do queries in app setup if you can avoid it. Use signals if you have to or lazy loading.
If you really have to, then flip the order of the apps. If it's the same app, then yes, don't do it: as you notice, you won't be able to do any migrations.

Django - can't run makemigrations: "no such table" even after running reset_db

I am unable to run makemigrations, migrate, or anything else (flush, reset_db from django-extensions) if I have a certain app in my INSTALLED_APPS.
The app is called issues and has one model:
class Issue(models.Model):
title = models.CharField(max_length=255)
description = models.CharField(max_length=1000)
sent = models.BooleanField()
And it was working before (makemigrations and migrate ran fine and I could use the app/model correctly), until I tried adding:
severity = models.IntegerField()
and tried to run makemigrations. I don't have the error or remember it anymore, but since then everything is broken, even after removing severity from the model.
Everything works if I remove the issues app from my settings.py.
The error I get:
madjura#madjura-E6228:~/workspace/budget/src$ python3.5 manage.py makemigrationsTraceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/sqlite3/base.py", line 337, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: issues_issue
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 341, in execute
django.setup()
File "/usr/local/lib/python3.5/dist-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/usr/local/lib/python3.5/dist-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/home/madjura/workspace/budget/src/issues/apps.py", line 16, in ready
issues.models.Issue.objects.check_and_send_unsent_issues()
File "/home/madjura/workspace/budget/src/issues/models.py", line 18, in check_and_send_unsent_issues
for issue in issues:
File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 256, in __iter__
self._fetch_all()
File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 1087, in _fetch_all
self._result_cache = list(self.iterator())
File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 54, in __iter__
results = compiler.execute_sql()
File "/usr/local/lib/python3.5/dist-packages/django/db/models/sql/compiler.py", line 835, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.5/dist-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python3.5/dist-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.5/dist-packages/django/db/backends/sqlite3/base.py", line 337, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: issues_issue
While issues is in INSTALLED_APPS I get the same error when running migrate, flush and reset_db.
I have tried running flush and reset_db with issues removed from INSTALLED_APPS, this did not solve the problem.
I have tried doing the above and then running makemigrations and migrate, this does also not work. As soon as I put issues back in INSTALLED_APPS everything is broken.
How can I fix this?
EDIT:
Maybe relevant, the issue model has a Manager with a function:
class IssueManager(models.Manager):
"""Manager for the Issue class."""
def check_and_send_unsent_issues(self):
"""
Checks for unsent Issue objects (Issue.sent = False) and attempts
to send them.
Issues that have been sent are deleted.
If the issue fails to be sent for whatever reason, it is not deleted.
Does nothing if there are no unsent issues.
This method is called once when the server starts.
"""
issues = self.get_queryset().filter(sent=False)
for issue in issues:
try:
make_issue(issue.title, issue.description)
issue.delete()
except PostIssueException:
pass
Using apps.py I check for unsent issues and post them on Gitlab.
EDIT 2:
Issue resolved by commenting the line below which appears in my apps.py, in ready():
issues.models.Issue.objects.check_and_send_unsent_issues()
Which somehow caused things to break, I don't understand why. Could someone explain that please?
Try moving the line import issues.models into def ready() to prevent loading the models too early.

Duplicate column name when migrating Django database

I am trying to migrate my database:
E:\PhytonProgects\natarelke>python manage.py migrate
System check identified some issues:
WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended
you activate it. See:
https://docs.djangoproject.com/en/1.10/ref/databases/#mysql-sql-mode
Operations to perform:
Apply all migrations: admin, auth, catalog, contenttypes, main, ordering, registration, sessions, users
Running migrations:
Rendering model states... DONE
Applying catalog.0002_auto_20170219_2146...Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 367, in execute_from_command_line
utility.execute()
File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 305, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 356, in execute
output = self.handle(*args, **options)
File "C:\Python27\lib\site-packages\django\core\management\commands\migrate.py", line 202, in handle
targets, plan, fake=fake, fake_initial=fake_initial
File "C:\Python27\lib\site-packages\django\db\migrations\executor.py", line 97, in migrate
state = self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "C:\Python27\lib\site-packages\django\db\migrations\executor.py", line 132, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "C:\Python27\lib\site-packages\django\db\migrations\executor.py", line 237, in apply_migration
state = migration.apply(state, schema_editor)
File "C:\Python27\lib\site-packages\django\db\migrations\migration.py", line 129, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "C:\Python27\lib\site-packages\django\db\migrations\operations\fields.py", line 84, in database_forwards
field,
File "C:\Python27\lib\site-packages\django\db\backends\mysql\schema.py", line 43, in add_field
super(DatabaseSchemaEditor, self).add_field(model, field)
File "C:\Python27\lib\site-packages\django\db\backends\base\schema.py", line 409, in add_field
self.execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\backends\base\schema.py", line 112, in execute
cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "C:\Python27\lib\site-packages\django\db\backends\mysql\base.py", line 112, in execute
return self.cursor.execute(query, args)
File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
django.db.utils.OperationalError: (1060, "Duplicate column name 'user_id'")
When I try to run python manage.py migrate I got errors shown above. Can anybody help me fix them?
It's a simple issue which I also faced.
It's nothing big just an issue of migrate command. Usually, when you make new models or new tables, you re-run old migrations along with the newly created ones. Of which sometimes the Django confuses I suppose over here.
Easiest solution what I found was.
1st empty your recycle bin.
then go to your migrations folder or folders( in case you have more than one app)
temporarily delete ( send all migration files such as 0001_initial.py 0002_auto_20170621_1006 etc. all of them to recycle bin.
Then re-run the commands python manage.py makemigrations and python manage.py migrate
*step 3: is temporary del. here you can also go back to recycle bin easily restore it in one click. (so del is safe)
I want to tell you my case. This only works if you be patient and you are sure about the changes.
Django 2.1
{% for crash in crashes %}
python manage.py makemigrations
Locate the conflict file (In the question catalog.0002_auto_20170219_2146.py or something)
Remove (copy in other file or don't close the file) temporally the columns that already exists into the database . (This is what you must be patient :/ ).
{% endfor %}
python manage.py migrate
Undo the change in files.
That's all, works for me.
Moral: if you found an conflict with migrate, you should fix it, dont remove all files.
There is a problem either in your DB, or your migrations, or both. If this is a new project, deleting the DB and all migrations, and recreating them with makemigrations will probably get you out of trouble.
To save your data, you can try reverting to a models.py that matches your DB, and use dumpdata to export your data to a JSON file.

python django issue with the migrations

Is there any way to deal with the migrations ?
I have been working with the version 1.8 of django, where, after doing any change in the models.py, we need to run the following commands -
python manage.py makemigrations
python manage.py migrate
Many a times, this gives an error. And it so happens that I have to rebuild the project as there is no way out.
I also tried the following way-outs, but none of them worked.
deleted the migrations folder
undo the changes to model.py
deleted the files inside the migrations folder
tried with flushing, squashing the migratios
it every times shows the following error with a very long error log of some unknown files.
Post Edit : Here's the whole log
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/core/management/commands/migrate.py", line 221, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/migrations/executor.py", line 110, in migrate
self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/migrations/executor.py", line 147, in apply_migration
state = migration.apply(state, schema_editor)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/migrations/migration.py", line 115, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/migrations/operations/fields.py", line 62, in database_forwards
field,
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/sqlite3/schema.py", line 179, in add_field
self._remake_table(model, create_fields=[field])
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/sqlite3/schema.py", line 147, in _remake_table
self.quote_name(model._meta.db_table),
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/base/schema.py", line 111, in execute
cursor.execute(sql, params)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/utils.py", line 97, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Library/Python/2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/sqlite3/base.py", line 318, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: zapp_post__new.specs_order_post_id
Here is the link to my project, which currently is showing the error. You can try running the application
What should be done in this case ?
Downloaded your code, deleted db.sqlite3, ran syncdb, everything worked fine.
Since you didnt have any sensitive data in your db i think that works for you.
Here's a little extra info for future:
When modifying migrations/DB manually or when you run into a problem with migrations you should consider these things:
You should NOT delete migrations folder
Migrations folder should always contain __init__.py file
All applied migrations are stored in django_migrations table, so if you delete all migration files and remake migrations (i.e. creating a new 0001_initial.py), running migrate wont do anything, because django thinks it's already applied
Sometimes deleting specific rows in django_migrations table and also modifying your tables structure (according to deleted rows) solves the problem, but you should know what you're doing.
So, the easiest solution when you run into a problem with migrations is deleteing all files in migrations folder (except __init__.py), deleting all rows in django_migrations table where app=your_app_name, droping all tables of your app, then remaking migrations and applying them.
But if you have sensitive data and you can't delete db, it gets more complicated

Categories