I'm using Django 1.9 and MySQL. I want to rename a field in my model. Let's look at model Choice
from the Django getting started tutorial.
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length = 200)
votes = models.IntegerField(default=0)
So, I want to rename the votes
field to votes_count
. I created an empty migration and add to operations following line:
migrations.RenameField (
model_name='choice',
old_name='votes',
new_name='votes_count',
),
After python manage.py migrate
, the field in the database table was renamed. But when I tried to use this model
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id);
try:
selected = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question':question,
'error_message':"You didn't select a choice."
})
else:
selected.votes_count += 1
selected.save()
return HttpResponseRedirect(reverse('polls:results', args=(question_id)))
I got:
Unknown column 'polls_choice.votes' in 'field list
Traceback:
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/backends/mysql/base.py" in execute
112. return self.cursor.execute(query, args)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in execute
226. self.errorhandler(self, exc, value)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/connections.py" in defaulterrorhandler
36. raise errorvalue
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in execute
217. res = self._query(query)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in
_query
378. rowcount = self._do_query(q)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in
_do_query
341. db.query(q)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/connections.py" in query
280. _mysql.connection.query(self, query)
The above exception ((1054, "Unknown column 'polls_choice.votes' in 'field list'")) was the direct cause of the following exception:
File "/home/verdigo/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "./polls/views.py" in vote
23. selected = question.choice_set.get(pk=request.POST['choice'])
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/models/manager.py" in manager_method
122. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/models/query.py" in get
381. num = len(clone)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/models/query.py" in __len__
240. self._fetch_all()
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/models/query.py" in _fetch_all
1074. self._result_cache = list(self.iterator())
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/models/query.py" in __iter__
52. results = compiler.execute_sql()
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/models/sql/compiler.py" in execute_sql
848. cursor.execute(sql, params)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/backends/utils.py" in execute
79. return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/utils.py" in
__exit__
95. six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/utils/six.py" in reraise
685. raise value.with_traceback(tb)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
File "/home/verdigo/venv/lib/python3.4/site-packages/django/db/backends/mysql/base.py" in execute
112. return self.cursor.execute(query, args)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in execute
226. self.errorhandler(self, exc, value)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/connections.py" in defaulterrorhandler
36. raise errorvalue
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in execute
217. res = self._query(query)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in
_query
378. rowcount = self._do_query(q)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/cursors.py" in
_do_query
341. db.query(q)
File "/home/verdigo/venv/lib/python3.4/site-packages/MySQLdb/connections.py" in query
280. _mysql.connection.query(self, query)
Exception Type: OperationalError at /polls/1/vote/
Exception Value: (1054, "Unknown column 'polls_choice.votes' in 'field list'")
It looks as if you created and ran a migration to rename the model field from votes
to votes_count
, but did not update the model at the same time.
When the Django tries to fetch the model from the db, it tries to select the votes
column because you still have a votes field in your models, and you get the error because the column doesn't exist in the database.
Creating a manual migration isn't normally necessary. Usually, you would rename the model field, run makemigrations
, then run migrate
. The advantage of letting Django create the migration is that you can be confident that the database is in sync with your models after you have run migrate.
Cause: This error occurs when a new one-to-many foreign key is created, pointing to the model with the forkey field and then generating the table
.
Solution: This problem can be solved by directly deleting the database and rebuilding it.
1: drop database database table;
2, re-create after deletion, before the code created, run directly
This is an issue that has persisted with me and lead me down a lot of rabbit holes dropping tables etc. A simple solution I have found is answering "N" when django asks you if you are renaming a field of that model (when running makemigrations). What that then essentially performs is a deletion of your previous field and creates the new field. Be careful as you may lose data on existing field so this works with fields which are either new or relatively easy to 'refill' their data required. You may need to run --fake if you get an error with regards to not being able to 'drop field' when migrating after makemigrations.
Update: I did the above for a Boolean field and my data was kept. Even though I said N, it seems as if it is essentially a renaming.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With