Djangoは、クラス定義(モデル)とデータベーステーブルとを関連付けるORM(Object-Relation Model)というフレームワークを採用しています。そのため、SQLやRDBのことが分からなくても、Python & Djangoの知識だけである程度データベースを利用することができます。
データベースとしては、PostgreSQL / MYSQL / Sqlite などが利用可能ですが、これらすべてが既存のテーブルに対して、カラムの追加・変更・削除処理をサポートしている訳ではありません。例えば、PostgreSQLはカラムの追加はできますが、変更(型や名前の変更など)はできません。
これらは、サポートしているデータベースが提供しているサービスで、共通部分のみしか使わないというDjangoの思想に基づいています。なので、モデル定義の変更・削除も同様に、
$ python manage.py syncdb
では対応できないのです。
これを解決するためのDjangoアプリケーションがあります。
「django-evolution」です。
これを使えば、モデルの変更・削除が実現できます。
まずは、上記django-evolutionのHPに行き、ソースをDLし、プロジェクトからパスの通っているアプリ置き場に移動させましょう。
(ちなみに、プロジェクトディレクトリ直下はデフォルトでパスが通っています。)
$ svn checkout http://django-evolution.googlecode.com/svn/trunk/ django-evolution
$ mv django-evolution project-dir
その後、settings.pyに、django-evolutionを登録します。
$ emacs settings.py
# 既にexternal_apps配下にディレクトリを展開したのでパスは通っている。
# あとは、INSTALLED_APPSに「django_evolution」の記述を追加する。
# mitarai
'jim',
'jim.movies',
'jim.userinfo',
'django_evolution',
$ ./manage.py syncdb
これで、django-evolutionがモデル定義の変更履歴を管理するためのテーブルが作成されます。従って、この時点からプロジェクト内のモデルが変更になると、evolutionが認識できるようになります。
あとは、モデル定義を変更した時に、以下のようにして、モデル定義を正しく変更するためのSQL文をGETすることができます。
$ ./manage.py evolve --hint --sql
当該コマンドで、変更点を反映させるSQL文を表示してくれる。
これをコピペして、
$ psql hoge.db
データベース内で、先ほどコピペしたSQL文を直接発行して変更を反映させる。
直接evolutionにテーブル定義を変更することを許可する場合は、以下のようにすればOKです。
$ ./manage.py evolve —execute —hint
でも、大量のデータが格納されている大切なテーブルを勝手に変更されるのは誰でも不安だと思いますので、「 —execute 」は付けずに、SQLを表示させて一旦妥当性を確認してテーブル定義の変更をすることをオススメいたします。
ちなみに、django-evolutionで管理しているモデル定義の変更履歴をリセットしたい場合は、以下のようにすることで実現可能です。
$ ./manage.py reset django_evolution
これで、次回以降「 sync db 」してもテーブル定義が変更されることはありません。