62

私が始めたプロジェクト (fyi、ブラウザベースのゲーム) に Django を使用することを検討しています。私が最も気に入っている機能の 1 つは、syncdb定義した Django モデルに基づいてデータベース テーブルを自動的に作成する機能です (a他のフレームワークには見られない機能です)。ドキュメントでこれを見たとき、私はすでにこれが本当であるには良すぎると思っていました:

Syncdb は既存のテーブルを変更しません

syncdb は、まだインストールされていないモデルのテーブルのみを作成します。インストール後にモデルクラスに加えられた変更に一致するように ALTER TABLE ステートメントを発行することはありません。モデル クラスとデータベース スキーマへの変更には、しばしば何らかの形式のあいまいさが含まれます。そのような場合、Django は正しい変更を推測する必要があります。プロセス中に重要なデータが失われるリスクがあります。

モデルに変更を加え、それに合わせてデータベース テーブルを変更したい場合は、sql コマンドを使用して新しい SQL 構造を表示し、それを既存のテーブル スキーマと比較して変更を確認します。

既存のテーブルの変更は「手作業」で行う必要があるようです。

私が知りたいのは、これを行うための最良の方法です。2 つの解決策が思い浮かびます。

  • ドキュメントが示唆するように、DB で手動で変更を行います。
  • データベースのバックアップを作成し、ワイプし、テーブルを再度作成します (syncdb を使用して、テーブルを最初から作成しているため)、バックアップしたデータをインポートします (データベースが大きい場合、これには時間がかかりすぎる可能性があります)。

何か案は?

4

7 に答える 7

61

SQLの変更とダンプ/リロードの両方を手動で行うことはどちらのオプションでもありますが、Djangoのスキーマ進化パッケージのいくつかをチェックすることもできます。最も成熟したオプションは、django-evolutionSouthです。

編集:そしてねえ、ここに移民が来る

更新:この回答が最初に書かれて以来、django-evolutiondmigrationsはどちらも活発な開発をやめ、SouthはDjangoのスキーマ移行の事実上の標準になりました。南の一部は、次のリリースまたは2つ以内にDjangoに統合される可能性もあります。

更新:Southに基づくスキーマ移行フレームワーク(およびSouthの作成者であるAndrew Godwinによって作成された)は、Django1.7以降に含まれています。

于 2008-08-30T14:56:49.777 に答える
17

同じトピックに対する他の回答で述べたように、YouTube でDjangoCon 2008 Schema Evolution Panelを必ずご覧ください。

また、マップ上の 2 つの新しいプロジェクト: SimplemigrationsMigratory

于 2008-10-09T12:16:02.317 に答える
9

これを行う良い方法の1つは、器具、特にinitial_data器具を使用することです。

フィクスチャは、データベースのシリアル化されたコンテンツを含むファイルのコレクションです。つまり、データベースのバックアップを作成するようなものですが、Djangoはそれを認識しているため、使いやすく、単体テストなどを行うときに追加のメリットがあります。

を使用して、現在DBにあるデータからフィクスチャを作成できますdjango-admin.py dumpdata。デフォルトでは、データはJSON形式ですが、XMLなどの他のオプションも使用できます。フィクスチャを保存するのに適した場所はfixtures、アプリケーションディレクトリのサブディレクトリです。

を使用してフィクスチャをロードできますが、さらに重要なことに、フィクスチャに、を実行すると自動的にロードされるdjango-admin.py loaddataような名前が付いている場合は、自分でフィクスチャをインポートする手間を省くことができます。initial_data.jsonsyncdb

もう1つの利点はmanage.py test、単体テストを実行するために実行すると、一時テストデータベースにも初期データフィクスチャがロードされることです。

もちろん、これは、モデルの属性とDBの列を追加するときに機能します。データベースから列を削除する場合は、フィクスチャを更新して、その列のデータを削除する必要がありますが、これは簡単ではない可能性があります。

これは、開発中にデータベースを少し変更する場合に最適です。本番DBを更新する場合、手動で生成されたSQLスクリプトが最適に機能することがよくあります。

于 2008-08-30T14:57:32.550 に答える
4

私は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)
    ]

もっとフィンガープリントと変更があれば、それをリファクタリングします。それまでは、それをよりクリーンにすることは、他の何かから開発時間を盗むことになります.

編集:とにかく変更を手動で作成していることを考えると、次回はdmigrationsを試します。

于 2008-09-11T02:44:47.623 に答える
3

django-command-extensionsは、manage.pyにいくつかの追加コマンドを提供するdjangoライブラリです。それらの1つはsqldiffであり、これにより、新しいモデルに更新するために必要なSQLが提供されます。ただし、「非常に実験的」と記載されています。

于 2008-09-11T23:33:07.000 に答える
2

これまでのところ、私の会社では手動のアプローチを使用してきました。何が最適かは、開発スタイルによって大きく異なります。

通常、運用システムではそれほど多くのスキーマ変更がなく、開発から運用サーバーへのある程度正式なロールアウトはありません。ロールアウトするたびに (年に 10 ~ 20 回)、現在および今後の運用ブランチの完全な差分を作成して、すべてのコードを確認し、運用サーバーで変更する必要があるものを確認します。必要な変更は、追加の依存関係、設定ファイルへの変更、およびデータベースへの変更である可能性があります。

これは私たちにとって非常にうまく機能します。すべてを自動化することはニッチなビジョンですが、私たちにとっては難しいことです。移行を管理できるかもしれませんが、追加のライブラリ、サーバー、その他の依存関係を処理する必要があります。

于 2009-01-04T14:26:54.233 に答える