質問
私が始めているプロジェクト (参考までに、ブラウザベースのゲーム) で Django の使用を検討していますが、最も気に入っている機能の 1 つは です。 syncdb
定義した Django モデルに基づいてデータベース テーブルを自動的に作成します (他のフレームワークでは見つからないようです)。これを見たとき、私はすでにこれはうますぎると思っていました ドキュメンテーション:
Syncdb は既存のテーブルを変更しません
syncdb は、まだインストールされていないモデルのテーブルのみを作成します。インストール後にモデル クラスに加えられた変更に一致する ALTER TABLE ステートメントを発行することはありません。モデル クラスやデータベース スキーマへの変更には、何らかの形のあいまいさが含まれることが多く、そのような場合、Django は行うべき正しい変更を推測する必要があります。この過程で重要なデータが失われるリスクがあります。
モデルに変更を加え、それに合わせてデータベース テーブルを変更したい場合は、sql コマンドを使用して新しい SQL 構造を表示し、それを既存のテーブル スキーマと比較して変更を解決します。
既存のテーブルの変更は「手動」で行う必要があるようです。
私が知りたいのは、これを行うための最良の方法です。2 つの解決策が思い浮かびます。
- ドキュメントが示唆しているように、DB に手動で変更を加えます。
- データベースのバックアップを実行し、データベースを消去し、テーブルを再度作成し (syncdb を使用します。テーブルを最初から作成するため)、バックアップされたデータをインポートします (データベースが大きい場合、これには時間がかかりすぎる可能性があります)。
何か案は?
解決
同じトピックに対する他の回答で述べたように、必ず見てください。 DjangoCon 2008 スキーマ進化パネル ユーチューブで。
他のヒント
SQL の変更とダンプ/リロードを手動で行うこともオプションですが、Django のスキーマ進化パッケージの一部をチェックアウトすることもできます。最も成熟したオプションは次のとおりです ジャンゴ進化 そして 南.
編集:そして、やあ、来ました 移民.
アップデート:この回答は元々書かれたものなので、 ジャンゴ進化 そして 移民 どちらも積極的な開発を停止しており、 南 は、Django のスキーマ移行の事実上の標準になっています。次の 1 ~ 2 回のリリースで、South の一部が Django に統合される可能性もあります。
アップデート:South に基づくスキーマ移行フレームワーク (South の著者である Andrew Godwin によって作成) は、Django 1.7 以降に含まれています。
これを行う良い方法の 1 つは、フィクスチャ、特に initial_data
備品。
フィクスチャは、データベースのシリアル化されたコンテンツを含むファイルのコレクションです。したがって、これはデータベースのバックアップを持つようなものですが、Django が認識しているものであるため、より使いやすく、単体テストなどを行うときに追加の利点があります。
次を使用して、DB に現在あるデータからフィクスチャを作成できます。 django-admin.py dumpdata
. 。デフォルトでは、データは JSON 形式ですが、XML などの他のオプションも使用できます。備品を保管するのに適した場所は、 fixtures
アプリケーションディレクトリのサブディレクトリ。
次を使用してフィクスチャをロードできます django-admin.py loaddata
しかし、さらに重要なのは、フィクスチャに次のような名前が付いている場合です。 initial_data.json
を実行すると自動的にロードされます syncdb
, 自分で輸入する手間が省けます。
もう 1 つの利点は、実行すると、 manage.py test
単体テストを実行するには、一時テスト データベースにも初期データ フィクスチャがロードされます。
もちろん、これはモデルに属性を追加したり、DB に列を追加したりするときにも機能します。データベースから列を削除する場合は、フィクスチャを更新してその列のデータを削除する必要がありますが、これは簡単ではない場合があります。
これは、開発中にデータベースに小さな変更を数多く行う場合に最も効果的です。実稼働 DB を更新するには、多くの場合、手動で生成した SQL スクリプトが最適に機能します。
私は django-evolution を使用しています。注意事項には次のようなものがあります。
- その自動提案は一様に腐っています。そして
- そのフィンガープリント関数は、異なるプラットフォーム上の同じデータベースに対して異なる値を返します。
そうは言っても、私は習慣を見つけました schema_evolution.py
便利にアプローチします。指紋の問題を回避するには、次のようなコードをお勧めします。
BEFORE = 'fv1:-436177719' # first fingerprint
BEFORE64 = 'fv1:-108578349625146375' # same, but on 64-bit Linux
AFTER = 'fv1:-2132605944'
AFTER64 = 'fv1:-3559032165562222486'
fingerprints = [
BEFORE, AFTER,
BEFORE64, AFTER64,
]
CHANGESQL = """
/* put your SQL code to make the changes here */
"""
evolutions = [
((BEFORE, AFTER), CHANGESQL),
((BEFORE64, AFTER64), CHANGESQL)
]
もっと多くの指紋と変更があれば、それを再因数分解するでしょう。それまでは、それをクリーンにすることは、他のものから開発時間を盗むことになります。
編集: とにかく手動で変更を構築していることを考えると、試してみます 移民 次回。
django コマンド拡張機能 これは、manage.py にいくつかの追加コマンドを提供する django ライブラリです。そのうちの 1 つは sqldiff で、新しいモデルに更新するために必要な SQL が提供されます。ただし、これは「非常に実験的」であると記載されています。
私の会社ではこれまで手動のアプローチを使用してきました。何が最適かは、開発スタイルによって大きく異なります。
通常、実稼働システムではそれほど多くのスキーマ変更はなく、開発サーバーから実稼働サーバーへのある程度正式なロールアウトは行われません。ロールアウトするたびに (年に 10 ~ 20 回)、現在および今後の本番ブランチのフィル diff を実行して、すべてのコードをレビューし、本番サーバーで変更する必要があるものを記録します。必要な変更としては、追加の依存関係、設定ファイルの変更、データベースの変更などが考えられます。
これは私たちにとって非常にうまくいきます。すべてを自動化するというのはニッチなビジョンですが、私たちにとっては非常に困難です。移行は管理できるかもしれませんが、それでも追加のライブラリ、サーバー、その他の依存関係を処理する必要があります。
Django 1.7 (現在開発中) は ネイティブサポートの追加 スキーマ移行の場合 manage.py migrate
そして manage.py makemigrations
(migrate
廃止される syncdb
).