• 4.2
  • 5.0
  • dev
  • ドキュメントのバージョン: 5.1

フィクスチャ (fixture)

フィクスチャとは何ですか?

フィクスチャ (fixture) とは、シリアライズされたデータベースのコンテンツを含むファイルのコレクションです。各フィクスチャにはユニークな名前があり、フィクスチャを構成するファイルは、複数のアプリケーションの複数のディレクトリに分散できます。

フィクスチャはどのように作成するべきですか?

フィクスチャは manage.py dumpdata によって生成できます。また、 シリアライゼーションツール を直接使って、あるいは手書きでカスタムフィクスチャを生成することもできます。

フィクスチャはどう使えばよいのですか?

フィクスチャは テスト 用のデータをあらかじめデータベースに投入するために使えます:

class MyTestCase(TestCase):
    fixtures = ["fixture-label"]

または 初期データloaddata コマンドを使って提供することもできます:

django-admin loaddata <fixture label>

Django はどこでフィクスチャを探しますか?

Django はこれらの場所でフィクスチャを探します:

  1. インストールされた各アプリケーションの fixtures ディレクトリ内

  2. FIXTURE_DIRS 設定にリストされている任意のディレクトリ内

  3. フィクスチャによって名前が付けられたリテラル パス内

Django は、指定されたフィクスチャ名と一致するフィクスチャをすべて読み込みます。指定されたフィクスチャに拡張子がある場合、そのタイプのフィクスチャだけが読み込まれます。たとえば

django-admin loaddata mydata.json

mydata と呼ばれる JSON フィクスチャのみを読み込みます。フィクスチャの拡張子は シリアライザ に登録された名前 (例: jsonxml) に対応していなければなりません。

拡張子を省略した場合、Django は利用可能なすべてのフィクスチャタイプから、マッチするフィクスチャを検索します。例えば

django-admin loaddata mydata

これは mydata というフィクスチャタイプのフィクスチャを探します。フィクスチャディレクトリに mydata.json が含まれていれば、そのフィクスチャは JSON フィクスチャとして読み込まれます。

命名されたフィクスチャはディレクトリ・コンポーネントを含むことができます。これらのディレクトリは検索パスに含まれます。たとえば:

django-admin loaddata foo/bar/mydata.json

これは、インストールされている各アプリケーションに対して <app_label>/fixtures/foo/bar/mydata.json を、 FIXTURE_DIRS 内の各ディレクトリに対して <dirname>/foo/bar/mydata.json を、そしてリテラルパス foo/bar/mydata.json を検索します。

フィクスチャが読み込まれる順番

複数のフィクスチャを同じ呼び出しで指定できます。たとえば:

django-admin loaddata mammals birds insects

またはテストケースクラスで:

class AnimalTestCase(TestCase):
    fixtures = ["mammals", "birds", "insects"]

フィクスチャが読み込まれる順番は、管理コマンドを使うときでも、上で示したようにテストケースクラスでリストアップするときでも、リストアップされた順番に従います。

これらの例では、すべてのアプリケーション( INSTALLED_APPS で定義されたアプリケーションの順番)から mammals という名前のすべてのフィクスチャが最初に読み込まれます。続いて、すべての birds フィクスチャが読み込まれ、続いてすべての insects フィクスチャが読み込まれます。

データベースのバックエンドが行レベルの制約をサポートしている場合、これらの制約はトランザクションの最後にチェックされることに注意してください。データベース構成が遅延制約チェックをサポートしていない場合、フィクスチャをまたぐリレーションシップは読み込みエラーになるかもしれません(例については MySQL のドキュメントを参照してください)。

フィクスチャはどのようにデータベースに保存されますか?

フィクスチャファイルが処理されると、データはそのままデータベースに保存されます。モデルで定義された save() メソッドは呼び出されず、 pre_savepost_save シグナルは raw=True で呼び出されます。インスタンスはモデルにローカルな属性しか持たないからです。例えば、フィクスチャの読み込み中に存在せず、例外を発生させるようなリレーション先フィールドにアクセスするハンドラを無効にしたい場合があるでしょう:

from django.db.models.signals import post_save
from .models import MyModel


def my_handler(**kwargs):
    # disable the handler during fixture loading
    if kwargs["raw"]:
        return
    ...


post_save.connect(my_handler, sender=MyModel)

このロジックをカプセル化するデコレータを書くこともできます:

from functools import wraps


def disable_for_loaddata(signal_handler):
    """
    Decorator that turns off signal handlers when loading fixture data.
    """

    @wraps(signal_handler)
    def wrapper(*args, **kwargs):
        if kwargs["raw"]:
            return
        signal_handler(*args, **kwargs)

    return wrapper


@disable_for_loaddata
def my_handler(**kwargs): ...

このロジックは、 loaddata の間だけでなく、フィクスチャがデシリアライズされるときは常にシグナルを無効にすることに注意してください。

圧縮されたフィクスチャ

フィクスチャは zipgzbz2lzmaxz フォーマットのいずれかに圧縮される場合があります。次に例を示します。

django-admin loaddata mydata.json

これは mydata.json, mydata.json.zip, mydata.json.gz, mydata.json.bz2, mydata.json.lzma, mydata.json.xz のいずれかを探します。圧縮アーカイブに含まれる最初のファイルが使用されます。

同じ名前で異なるフィクスチャタイプを持つ2つのフィクスチャが見つかった場合(例えば、 mydata.jsonmydata.xml.gz が同じフィクスチャディレクトリで見つかった場合)、フィクスチャのインストールは中断され、 loaddata の呼び出しでインストールされたデータはデータベースから削除されることに注意してください。

MyISAM を使用した MySQL とフィクスチャ

MySQL の MyISAM ストレージエンジンはトランザクションや制約をサポートしていないため、 MyISAM を使用する場合、フィクスチャデータの検証や、複数のトランザクションファイルが見つかった場合のロールバックはできません。

データベース別のフィクスチャ

複数のデータベースをセットアップしている場合、あるデータベースには読み込ませたいが、別のデータベースには読み込ませたくないフィクスチャ・データがあるかもしれません。このような状況では、フィクスチャの名前にデータベース識別子を追加できます。

例えば、 DATABASES 設定に users データベースが定義されている場合、フィクスチャの名前を mydata.users.json または mydata.users.json.gz とすると、 users データベースにデータを読み込むと指定したときだけフィクスチャが読み込まれます。

Back to Top