70

I've already defined a model and created its associated database via manager.py syncdb. Now that I've added some fields to the model, I tried syncdb again, but no output appears. Upon trying to access these new fields from my templates, I get a "No Such Column" exception, leading me to believe that syncdb didn't actually update the database. What's the right command here?

akki
  • 2,021
  • 1
  • 24
  • 35
theactiveactor
  • 7,314
  • 15
  • 52
  • 60

8 Answers8

138

As of Django 1.7+, built-in migrations support, allows for database schema migrations that preserve data. That's probably a better approach than the solution below.

Another option, not requiring additional apps, is to use the built in manage.py functions to export your data, clear the database and restore the exported data.

The methods below will update the database tables for your app, but will completely destroy any data that existed in those tables. If the changes you made to your app model do not break your old schema (for instance, you added a new, optional field) you can simply dump the data before and reload it afterwards, like so:

Django 1.4.15 and earlier

python manage.py dumpdata <your_app> > temp_data.json
python manage.py reset <your_app>
python manage.py loaddata temp_data.json

Django 1.5 and newer

python manage.py dumpdata <your_app> > temp_data.json
python manage.py sqlclear <your_app> | python manage.py dbshell
python manage.py syncdb
python manage.py loaddata temp_data.json

(The reset command was deprecated and then removed in Django 1.5)

If your changes break your old schema this won't work - in which case tools like South or Django Evolution are great.

zlovelady
  • 4,037
  • 4
  • 32
  • 33
  • I think this solution is best. – xiao 啸 May 25 '10 at 15:22
  • +1 like to use some thing that is already in django without any other django app. required – Hafiz Apr 08 '12 at 11:33
  • 20
    For django 1.5.1 users: manage.py reset is no longer supported. The flush can be used to delete everything. You can also use ALTER TABLE or DROP TABLE statements manually (from django ref): python manage.py flush – Ali May 08 '13 at 17:50
  • if I add field is ManyToManyField, the Error: Unable to serialize database: (1146, "Table 'gavacafe.subject_subject_vote_users' doesn't exist") – liuzhijun May 29 '13 at 01:53
  • In Django 1.7, you can do this with native `migrations` – user83039 Jan 12 '15 at 04:13
44

As of Django 1.7, you can now do this with native migrations. Just run

python manage.py makemigrations <your app name>
python manage.py migrate
Cassidy Laidlaw
  • 1,318
  • 1
  • 14
  • 24
33

Seems like what you need is a migration system. South is really nice, working great, has some automation tools to ease your workflow. And has a great tutorial.


note: syncdb can't update your existing tables. Sometimes it's impossible to decide what to do automagicly - that's why south scripts are this great.

kender
  • 85,663
  • 26
  • 103
  • 145
  • 6
    thanks for pointing out this interesting tool. For anyone interested, there's a insightful discussion about django database migration here: http://code.djangoproject.com/wiki/SchemaEvolution – theactiveactor Dec 31 '09 at 15:37
  • The link of South shows, "South has been deprecated. From Django 1.7 upwards, migrations are built into the core of Django. If you are running a previous version, you can find the repository on BitBucket.". So... what now? – WesternGun Nov 07 '17 at 14:38
  • links in the answer are broken – Shivaraj Patil Nov 24 '17 at 14:34
9

Django's syncdb doesn't alter existing tables in the database so you have to do it manually. The way I always do it is:

  1. Change the model class first.
  2. Then run: manage.py sql myapp.
  3. Look at the sql it prints out and see how it represented the change you are going to make.
  4. Make the change manually using your database manager.
  5. Check to see if everything worked correctly using the admin site.

If you are using sqllite a good manager is the firefox plugin: link

Juan Besa
  • 4,401
  • 5
  • 24
  • 25
8

Another tool would be django evolution. No table dropping needed in most cases.

django evolution

Just install it as any other django app and run:

python manage.py evolve --hint --execute

Thomas Kremmel
  • 14,575
  • 26
  • 108
  • 177
3

deseb is a great tool for that.

Having it installed, you can write ./manage.py sqlevolve and it'll generate sql commands necessary to keep the database structure in sync with your models.

Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
2

You need to drop your tables before you can recreate them with syncdb.

If you want to preserve your existing data, then you need to unload your database, drop your tables, run syncdb to build a new database, then reload your old data into your new tables.

There are tools that help with this. However, in many cases, it's just as easy to do it manually.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
1

For versions 1.4.1 and above users the command has changed to

python manage.py flush

Please read the official document before using it as it will delete all your data.

akki
  • 2,021
  • 1
  • 24
  • 35
  • What I don't understand is flush actually resets the database as it was after `syncdb` was executed, but what about the potentially newly added fields ? They don't get created – Pierre de LESPINAY Sep 05 '14 at 12:04