モデルに初期データを投入する

revision-up-to:17812 (1.4)

アプリケーションを最初にセットアップするときに、データベースにハードコード されたデータを投入できると便利なことがあります。 Django に自動的に初期デー タを投入させる方法は二つあります: ひとつは フィクスチャによる初期データの 投入 で、もう一つは SQL による初 期データの投入 です。

フィクスチャによる初期データの投入

フィクスチャ (fixture) とは、 Django のデータベースに投入できるよう準備済み のデータの集まりです。すでにデータの入ったデータベースを持っているなら、フィ クスチャの生成には manage.py dumpdata コマンドを使うのが 一番簡単です。フィクスチャは手でも書けます。フィクスチャは XML, YAML または JSON ドキュメント形式で書けます。サポートされている シリアライゼーション フォーマット の詳細は シリアライゼーションのド キュメント を参照してください。

とはいえ、一例として、 JSON で書かれた Person モデルのフィクスチャを示 しておきます:

[
  {
    "model": "myapp.person",
    "pk": 1,
    "fields": {
      "first_name": "John",
      "last_name": "Lennon",
    }
  },
  {
    "model": "myapp.person",
    "pk": 2,
    "fields": {
      "first_name": "Paul",
      "last_name": "McCartney",
    }
  },
]

YAML で書くと以下のようになります:

- model: myapp.person
  pk: 1
  fields:
    first_name: John
    last_name: Lennon
- model: myapp.person
  pk: 2
  fields:
    first_name: Paul
    last_name: McCartney

フィクスチャデータはアプリケーションの fixture ディレクトリに保存します。

データのロードは簡単で、単に manage.py loaddata を実行するだけです。 <fixturename> はフィクスチャファイルの名 前です。 loaddata を実行するたびに、フィクスチャデータが読み出さ れ、データベースにリロードされます。つまり、フィクスチャによって生成されたレ コード行を変更して loaddata を再度実行すると、変更後のデータは消去 されてしまうのです。注意してください。

初期データフィクスチャの自動ロード

initial_data.[xml/yml/json] という名前のフィクスチャを作成しておくと、 syncdb を実行するたびに自動的にロードされます。この機能はとても 便利なのですが、一つだけ注意が必要です。というのも、 syncdb を実行するたびに 毎回 データがリフレッシュされるからです。ですから、 変更する予定のデータに initial_data を使ってはなりません。

Django がフィクスチャファイルを探す場所

デフォルトでは Django は各アプリケーション内の fixtures ディレクトリから フィクスチャを探します。 FIXTURE_DIRS に Django が調べるべき追加 ディレクトリのリストを設定することができます。

manage.py loaddata を実行する時にフィクスチャの絶対パス を指定することもできます。これは通常のディレクトリからの探索を上書きします。

See also

フィクスチャは テストフレームワーク で 一貫したテスト環境を構築するためにも使われています。

SQL による初期データの投入

Django には、データベースに任意の SQL を渡すためのフックがあります。 この SQL は、 syncdb を実行した時に CREATE TABLE 文の直後に実行されま す。このフックを使えば、自動的にデフォルトのレコードをテーブルに追加したり、 SQL関数やビュー、トリガなどを作成したりできます。

フックのからくりは単純です: Django はアプリケーション内の sql/<modelname>.sql という名前のファイルを探し、実行するだけです。 <modelname> は、モデル名を小文字にした文字列です。

このドキュメントの冒頭にある Person の例で、モデルが myapp の下に置 かれていたとすると、 myapp/sql/person.sql というファイルに任意の SQL 文 を指定できます。例えば以下のような命令を入れられます:

INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');

各 SQL ファイルには、必要なデータを INSERT するための有効な SQL 文を (すなわち、正しくフォーマットされた INSERT 文をセミコロンで区切って) 入 れておかねばなりません。

SQL ファイルは manage.pysqlcustom sqlreset, sqlall および reset コマンドの実 行時に参照されます。詳しくは manage.py のドキュメント を参照してください。

複数の SQL データファイルがある場合、個々のファイルを実行する順番は保証され ていないので注意して下さい。仮定していてよいのは、カスタムの SQL データファ イルを実行する前に、必ずデータベーステーブルは作成されているということだけ です。

初期 SQL データとテスト

テスト用の初期データを提供するためにこのテクニックを使うことは できません 。 Django のテストフレームワークは、全てのテストの後ごとにテ ストデータベースの内容をクリアします。結果として、カスタム SQL フックを 使って追加した全てのデータが失われることになります。

テストケースのためにデータが必要なら、 テストフィクスチャ を使って追加するか、 テストケースの setUp() でプログラム的に追加する必要があります。

データベースバックエンド特有の SQL データ

バックエンド特有の SQL データに対するフックもあります。例えば、 PostgreSQL と MySQL 向けに別々の初期データを用意できます。各アプリケーションごとに Django は <appname>/sql/<modelname>.<backend>.sql というファイルを探し ます。 <appname> はアプリケーションディレクトリの名前、 <modelname> はモデル名を小文字にした文字列、 <backend> は設定ファイルの ENGINE に指定するモジュール名の最後の部分です。 (ENGINE の値に django.db.backends.sqlite3 に定義したなら Django は <appname>/sql/<modelname>.sqlite3.sql を探します)

バックエンド固有の SQL データは、バックエンド非固有の SQL データよりも前に 実行されます。例えば、アプリケーション中に sql/person.sql および sql/person.sqlite3.sql が入っていて、 SQLite をバックエンドにしてインス トールを行った場合、 Django はまず sql/person.sqlite.sql の内容を実行して から sql/person.sql を実行します。