environment DJANGO VERSION 1.9 Python 2.7.6
I added a field (scores) to a model class in models.py like this
from django.db import models
from django
Easyes Solution: RENAME the field makemigrations migrate RENAME back makemigrations migrate
Well the problem is NOT with your makemigrations command or models.py. It is because you have probably imported your class in the model (your database in this case) in on of your views.py files and the problem is with that. If you read the all of the error message then you can understand that easily.
Just try commenting that importing part and run your python.manage.py makemigrations and python manage.py migrate commands then you can uncomment your import in your views.py file
Hope this was useful for others as well
Those migration issues bother me too when i have to update my app with new columns, so i've made a small bash with some python to search for troublesome columns, remove them, migrate, re-add them and migrate again.
Here is the resolve.sh
that calls python and migrations (has to be placed in the same folder as your manage.py
file, like the .py
files) :
python manage.py shell < check.py
read -p "Does it seem ok ? (y for ok/n for remigrate)" migrateok
if [ $migrateok = "n" ]
then
python manage.py shell < rm_badcolumns.py
python manage.py makemigrations
sleep 1
python manage.py migrate
python manage.py shell < resume_badcolumns.py
python manage.py makemigrations
sleep 1
python manage.py migrate
echo It should work now..
else
echo No changes were made..
fi
check.py
checks if there are issues with some models in the database :
from <app>.models import *
import os, sys
from shutil import move
from django.db import connection
tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)
errorColumn = []
is_fine = "EVERYTHING LOOKS FINE!"
#looping through models to detect issues
for model in seen_models:
try:
print(model.objects.all())
except:
is_fine = "WARNING SOME MODELS ARE CORRUPTED"
print(is_fine)
This check will tell the user if some models are not sync with your database.
If the user chooses to "re-migrate", it calls rm_badcolumns.py
:
from <app>.models import *
import os, sys
from shutil import move
from django.db import connection
tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)
errorColumn = []
for model in seen_models:
try:
model.objects.all()
except:
errorColumn.append(str(sys.exc_info()[1])[30::]+' =')
#this weird expression just get the column that causes trouble
#you may have to adapt indexes depending on error output in exc_info
os.chdir('./<app>/')
#removing columns from models.py based on the error pattern
def replace(pattern, subst):
with open('models_sub.py','w') as fout:
with open('models.py','r') as models:
for line in models:
fout.write(line.replace(pattern, subst))
os.remove('models.py')
move('models_sub.py','models.py')
#applying this func to each error, and commenting out columns with an error mark to catch them back later
for errorStr in errorColumn:
replace(errorStr, '#error_mark '+errorStr)
print 'Removing troublesome column for re-entering..'
Then resolve.sh
will start another migration.
We uncomment the troublesome columns with resume_badcolumns.py
to get them migrated again :
from <app>.models import *
import os, sys
from shutil import move
from django.db import connection
os.chdir('./<app>/')
#same search and replace func but returning True if sthg was replaced, and False otherwise
def replace(pattern, subst):
a = False
with open('models_sub.py','w') as fout:
with open('models.py','r') as models:
for line in models:
fout.write(line.replace(pattern, subst))
if pattern in line:
a = True
os.remove('models.py')
move('models_sub.py','models.py')
return a
a = True
#while error_marks are replaced, we go on looping
while a:
a = replace('#error_mark ', '')
print 'Re-adding troublesome columns..'
We make a final migration and everything should be fine.
This is a kind of heavy and dirty artillery for a small problem but i wanted it to be automatized. A few points may need some rework, such as the way i identify which column is not synced, and i'd appreciate comments about this.
Fast fix.
First remove field scores
, Then
python manage.py makemigrations
python manage.py migrate
If any error happens
python manage.py migrate --fake
Then add field scores
.Then
python manage.py makemigrations
python manage.py migrate
Hope this helps.
Keeping it short and precise, give that field a default value.
For example:
nickname = models.CharField(max_length=12, default=" ")
and not default=True
If that doesn't work delete the migrations in your app's migration folder except
__init__.py file and type both the commands again.
python manage.py migrate
python manage.py makemigrations appname
python manage.py migrate(again)
All, that u need: download «DB Browser for SQLite» and:
Yeah, 5-10 minutes to do it, but all is work)
image1
image2
image3
result