ORM

Django ORMの初期データ投入入門|fixtures・シェルコマンド

Django ORM 初期データ

Django ORMの初期データ投入入門
fixtures・シェルコマンド

Djangoでデータベースに初期データを投入する方法を解説します。fixturesとDjangoシェルの2つのアプローチを紹介します。

こんな人向けの記事です

  • 開発環境にテストデータを投入したい人
  • fixturesの使い方を知りたい人
  • Djangoシェルからデータを作成したい人

Step 1初期データ投入の方法

Djangoで初期データを投入する方法は主に3つあります。

方法用途
Djangoシェル少量のデータを手動で投入する場合
fixtures(JSON/YAML)定型的な初期データを管理する場合
カスタム管理コマンド複雑な初期データを投入する場合

Step 2Djangoシェルでデータを作成する

最も手軽な方法は、Djangoシェルから直接データを作成する方法です。

ターミナル
python manage.py shell
Python
from myapp.models import Company

# 1件ずつ作成
Company.objects.create(name="株式会社A", founding_date="2010-04-01")
Company.objects.create(name="株式会社B", founding_date="2015-07-15")

# 作成されたデータを確認
for c in Company.objects.all():
    print(f"{c.id}: {c.name}")
実行結果
1: 株式会社A
2: 株式会社B

Step 3fixturesでデータを定義する

fixturesはJSON形式でデータを定義し、コマンドで一括投入する仕組みです。アプリケーション内にfixturesフォルダを作成し、JSONファイルを配置します。

myapp/fixtures/initial_data.json
[
  {
    "model": "myapp.company",
    "pk": 1,
    "fields": {
      "name": "株式会社A",
      "founding_date": "2010-04-01"
    }
  },
  {
    "model": "myapp.company",
    "pk": 2,
    "fields": {
      "name": "株式会社B",
      "founding_date": "2015-07-15"
    }
  }
]

fixturesを読み込むには以下のコマンドを実行します。

ターミナル
python manage.py loaddata initial_data
実行結果
Installed 2 object(s) from 1 fixture(s)

ポイント: fixturesファイルはアプリケーションフォルダ内のfixturesディレクトリに配置します。Djangoが自動的に検索してくれます。

Step 4fixturesの読み込みと書き出し

既存のデータベースからfixturesファイルを書き出すこともできます。

ターミナル
# 全データをJSON形式で書き出し
python manage.py dumpdata myapp --indent 2 > myapp/fixtures/all_data.json

# 特定のモデルのみ書き出し
python manage.py dumpdata myapp.company --indent 2 > myapp/fixtures/companies.json

# fixturesを読み込み
python manage.py loaddata companies

注意: loaddataは同じ主キーのデータが存在する場合、上書きします。重複データの投入に注意してください。

Step 5カスタムコマンドでデータを投入する

複雑なデータ投入にはカスタム管理コマンドを作成します。

myapp/management/commands/seed.py
from django.core.management.base import BaseCommand
from myapp.models import Company

class Command(BaseCommand):
    help = "初期データを投入します"

    def handle(self, *args, **options):
        # 既存データを削除
        Company.objects.all().delete()

        companies = [
            {"name": "株式会社A", "founding_date": "2010-04-01"},
            {"name": "株式会社B", "founding_date": "2015-07-15"},
            {"name": "株式会社C", "founding_date": "2020-01-10"},
        ]

        for data in companies:
            Company.objects.create(**data)
            self.stdout.write(f"作成: {data['name']}")

        self.stdout.write(self.style.SUCCESS("初期データの投入が完了しました"))
ターミナル
python manage.py seed

ポイント: カスタムコマンドはアプリ名/management/commands/フォルダに配置します。managementフォルダとcommandsフォルダの両方に__init__.pyファイルが必要です。

Step 6関連するモデルのデータ投入

外部キーで関連するモデルのデータを投入する例です。

Python
from myapp.models import Company, Employee

# 会社データを作成
company_a = Company.objects.create(name="株式会社A", founding_date="2010-04-01")
company_b = Company.objects.create(name="株式会社B", founding_date="2015-07-15")

# 社員データを作成(会社との関連付け)
Employee.objects.create(name="田中太郎", email="tanaka@example.com", age=32, company=company_a)
Employee.objects.create(name="佐藤花子", email="sato@example.com", age=28, company=company_a)
Employee.objects.create(name="鈴木一郎", email="suzuki@example.com", age=45, company=company_b)

fixturesで関連データを定義する場合は、外部キーのフィールドにpk値を指定します。

myapp/fixtures/employees.json
[
  {
    "model": "myapp.employee",
    "pk": 1,
    "fields": {
      "name": "田中太郎",
      "email": "tanaka@example.com",
      "age": 32,
      "company": 1
    }
  }
]

まとめ

  • DjangoシェルでModel.objects.create()を使って手軽にデータを作成できる
  • fixturesはJSON形式で初期データを管理し、loaddataで投入する
  • dumpdataで既存データをfixturesとして書き出せる
  • 複雑な初期データにはカスタム管理コマンドが便利
  • 関連モデルのデータ投入では、親データを先に作成してから子データに紐づける