※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。


【Django】データベースのダンプファイル取り扱い方解説

python3 Django サーバー運用 ダンプ Django3 バックアップ DB

投稿日:2021年6月16日

このエントリーをはてなブックマークに追加
この記事ではDjangoコマンドを使ったダンプファイルの作成・読み込みの方法などについて詳しく解説しています。

はじめに

この記事について

Web開発で、アプリケーションの初期データやバックアップのためにダンプ作成は必須の知識です。実ははDjangoにはデフォルトこれを行うためのコマンドが用意されています。
この記事ではDjangoコマンドを使ったダンプファイルの作成・読み込みの方法などについて詳しく解説しています。

環境について

この記事は以下の環境で確認されました。

  • python version 3.7.3
  • Django version 3.2

dumpdata

django-adminとmanage.pyにはdumpdataというコマンドが用意されています。そのコマンドを使うことで簡単にDjango用のDBダンプファイルを作成することができます。

使い方

dumpdataコマンドはデフォルトで全てのデータをjson形式で出力できます。出力ファイル名は-oオプションで指定しましょう。

$ python manage.py dumpdata -o dump.json

出力ファイルは以下のようになっています。

dump.json
[
  {
    "model": "contenttypes.contenttype",
    "pk": 1,
    "fields": {
      "app_label": "admin",
      "model": "logentry"
    }
  },


    // [...]

        {
        "model": "schedules.schedule",
        "pk": 1,
        "fields": {
            "title": "myschedule"
        }
    },
    {
        "model": "schedules.task",
        "pk": 1,
        "fields": {
            "schedule": 1,
            "user": 1,
            "title": "sample task",
            "content": "asdfasdfasdf",
            "start_time": "2021-06-15T02:39:19Z",
            "end_time": "2021-06-15T02:39:22Z"
        }
    },
    {
        "model": "schedules.task",
        "pk": 2,
        "fields": {
            "schedule": 1,
            "user": 1,
            "title": "kkk",
            "content": "\"dfasdfasfd\"",
            "start_time": "2021-06-15T02:39:43Z",
            "end_time": "2021-06-15T02:39:49Z"
        }
    },
]

特定のテーブルのみのダンプをとることもできます。コマンドの引数にapp名を渡すことで、対象app内の全てのテーブルをダンプします。またapp名.テーブル名を渡すことで特定のテーブルのみをダンプすることができます。

appのテーブル全体をダンプ
$ python manage.py dumpdata schedules
特定のテーブルのみをダンプ
$ python manage.py dumpdata schedules.Task

引数は複数指定できるため、複数のapp、テーブルをダンプすることもできます。

複数のappをダンプ
$ python manage.py dumpdata -o dump.json schedules accounts
複数のテーブルをダンプ
$ python manage.py dumpdata -o dump.json schedules.Task schedules.Schedule

その他の使い方については公式ドキュメントを参照してください。

ダンプデータについて

出力されるダンプデータは以下のようなオブジェクトの配列になっています。

  • "model" : 対象テーブル、app名.テーブル名の形になる。
  • "pk" : テーブルの主キーの値。デフォルトの場合、DBのカラム名"id"の値
  • "fields" : レコードの値。ただし、主キーは除かれる

loaddata

django-adminmanage.pyにはloaddataというコマンドも用意されています。loaddumpはダンプデータをDBにインサートすることができます。

使い方

loaddataには引数としてダンプファイルを指定します。

ターミナル
$ python manage.py loaddata dump.json

ダンプファイルは以下の順に探しに行きます。

  1. settingsINSTALLED_APPSに指定したすべてのアプリケーションのディレクトリ直下の引数値のディレクトリ
  2. settingsINSTALLED_APPSのアプリケーションのFIXTURE_DIRSに指定したディレクトリ
  3. 引数値を相対パスとした場所

読み込むデータについては--excludeで除外するappのラベルを指定することができます。例えば、一部テーブルは他のリソースから読み込みたい場合などは対象テーブルだけ除外しておくといいでしょう。

schedulesのappのみ除外
$ python manage.py loaddata --exclude schedules dump.json

その他の使い方については公式ドキュメントを参照してください。

データの重複

同じプライマリーキーのレコードがすでにDBに存在したとしても、コマンドは正常に終了します。普段DBのdumpコマンドを利用している人にとっては、これは奇妙に見えるかもしれません。
実はloaddataコマンドは対象テーブルを一旦すべて取得してきて、対象jsonと比較した後、再度データを入れ直しているのです。

データのフォーマット

読み込むデータは必ずしもdumpdataコマンドで生成したjsonである必要はありませんが、Djangoのシリアライズサポートを満たしている形式である必要があります。

json以外の形式を読み込む場合には--formatオプションで形式を指定しましょう。

xmlを読み込む
$ python manage.py loaddata --format xml dump.xml

またダンプファイルがzip, gz, bz2, lzma, xzで圧縮してある場合でも、そのまま読み込むことができます。
便利〜!!!

dump.json.zipを読み込む
$ python manage.py loaddata dump.json

Djangoコマンドでやる意味って?

ほとんどのRDMSはデータをダンプする方法を既に提供しています。
それなのにDjangoのコマンドでする意味はあるのでしょうか?

そこで、ここではDjangoコマンドを使う場合のメリット・デメリットについて解説します。

【メリット】RDMS差異の吸収

Djangoコマンドの大きなメリットは2つあります。
1つ目はDjangoによって、使用データベースの差異を吸収できる点です。

では例を元にアプローチを見てみましょう。

Djangoアプリケーションではじめのうちはmysqlデータベースを使っていたとします。その後改修を重ねていく中でpostgresqlのみの機能を使いたくなり、データベースを変更することになりました。そのような場合でもDjangoコマンドなら簡単に以降できます。

まずは設定ファイルは以下のようになっているとします。

settings.py
# [...]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': ‘<db_name>’,
        'USER': '<db_username>',
        'PASSWORD': '<password>',
        'HOST': '<db_hostname_or_ip>',
        'PORT': '<db_port>',
    }
}

# [...]

ここでサービスを一旦止めて、現在のデータのダンプを作成します。

ターミナル
$ python manage.py dumpdata dump.json

次のデータベースのライブラリをインストールします。

ターミナル
$ pip install psycopg2

ここで設定ファイルを書き換えます。

settings.py
# [...]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': ‘<db_name>’,
        'USER': '<db_username>',
        'PASSWORD': '<password>',
        'HOST': '<db_hostname_or_ip>',
        'PORT': '<db_port>',
    }
}

# [...]

後はもとのデータベースを反映させれば移行は完了です。

ターミナル
$ python manage.py migrate # テーブル定義の反映
$ python manage.py loaddata dump.json # データの反映

簡単ですね!

使うDBによってクライアントライブラリと設定ファイルは違うものの基本的にすべて同じやり方で移行することができます。簡単な方法を使ってDBの移行ができることは非常に大きなメリットであると言えるでしょう。

【デメリット】他フレームワークで使用できない

基本的にdumpdateでとったデータはDjangoでしか使用できません。
理由は、以下のようにダンプデータの形式がDjangoのModelに依存しているためです。

  • "model"キーはDjangoのapp名.テーブル名の形式
  • "pk"という謎の値(Djangoでは謎ではない
  • 何故か"fields"には"id"のカラムが含まれない

結論

結論から言うと、Djangoを使うことが決定しているのであれば基本的にはDjangoコマンドを使うほうが楽だと思います。

このエントリーをはてなブックマークに追加


関連記事

記事へのコメント