While surfing through Stack Overflow, I find a common question among Django users that, database not working properly; fields attribute changed, yet not working etc. Clearly because most of them used syncdb after altering fields. Well, lets make some things clear here about django syncdb and migration.
syncdb is a command which is executed in django shell to create tables for first time for apps which are added to INSTALLED_APPS of settings.py. Need to keep in mind about two key words: ‘First Time’ and ‘Newly Added Apps’. Because syncdb only works on models of those apps for first time to create initial tables in database. So once syncdb is executed, not model field altering, because if anyone does that, it will not work. Its clearly mentioned in django’s documentation:
syncdb will only create tables for models which have not yet been installed. It will never issue ALTER TABLE statements to match changes made to a model class after installation. Changes to model classes and database schemas often involve some form of ambiguity and, in those cases, Django would have to guess at the correct changes to make. There is a risk that critical data would be lost in the process. If you have made changes to a model and wish to alter the database tables to match, use the sql command to display the new SQL structure and compare that to your existing table schema to work out the changes. So what if you need to change model field? No worries, migration is here to save you.
Migration is a process to reconstruct database schema according to altered model fields. From Django 1.7 documentation:
So, after using syncdb, if you need to alter model fields, then go ahead, and after that you have to migrate database. If you are using django <=1.6, then you can use Django South. If django is above 1.6, it has its own database migration process.
And of course, if you use South to migrate, you have to use syncdb before executing migration, because if you don’t, initial database tables(including auth, auth_group_permission, django_admin_log etc) will not be created.
If you end up doing syncdb initially but need to change database, what should be done?
Easy solution, keep the models in same state as it was during initial syncdb command. Then run
python manage.py schemamigration your_app_label --initial(in django <=1.6) or
python manage.py makemigration your_app_label(django >=1.7).
After that, run
python manage.py migrate your_app_label --fake(in django <=1.6) or
python manage.py migrate your_app_label --fake-initial (django >=1.7). It will put a fake migration in the database which will occur no change in tables.
Then change models and run
python manage.py migrate your_app_label
PS: syncdb is deprecated from django 1.7, which will reduce the hassle of using syncdb and migration separately.
If you like this article, you can buy me a coffee. Thanks!
Last updated: Nov 20, 2023