【Django】dumpdata&loaddataコマンドでデータを他のSQL(SQLite3・MySQL・PostgreSQL・...)へ移動

投稿日 2020年9月1日 >> 更新日 2023年3月1日

今回は、Djangoの管理タスク用コマンドの「dumpdata」と「loaddata」を使用して、既存のデータベース内に保存されているデータを他のSQL(SQLite3・MySQL・PostgreSQL・...)へ移動、もしくわ移行していきたいと思います。

よくありそうなことで、DjangoではデフォルトでSQLite3を使用できることから、MySQLなどの大規模なデータベースを設定するタイミングを逃し、そのまま小規模なSQLite3を使用していることが多々あるかと思います。

他にも、特定のモデルに保存されているデータを他のアプリのデータベースに移動させるといった事です。

ここではSQLite3からMySQLのデータベースへデータを移動させる例を詳しく行っていきますが、PostgreSQLも同じような要領で移動、もしくわ移行・切り替えができるのでぜひ試してみて下さい。

実行環境&使用ライブラリ

実行環境
Windows Subsystem for Linux
Python3.6.9
pip 9.0.1
使用ライブラリ ライセンス
Django==3.1 BSD
mysqlclient==2.0.1(MySQLのドライバ) GNU General Public License (GPL)
psycopg2-binary==2.8.5(PostgreSQLのドライバ) GNU Library or Lesser General Public License (LGPL)

準備

それぞれ使用先のSQLドライバをインストールします。


# MySQLのドライバ
$ pip install mysqlclient

or

# PostgreSQLのドライバ
$ pip install psycopg2-binary

前提としているモデルフィールド

「models.py」では以下のような設定となっています。

# app/models

from django.db import models


class Todo(models.Model):
    title = models.CharField(max_length=50)
    created_at = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.title

データベースの作成(MySQL)

ここでは「SQLite3」→「MySQL」へ切り替えてデータを移動させるといった流れとするので、先にMySQLを起動してデータベースを作成しておきます。


$ mysql -u root -p
mysql> # データベースの一覧を取得
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

mysql> # データベース「testdb」を作成
mysql> create database testdb;
Query OK, 1 row affected (0.03 sec)

mysql> # もう1度データベースの一覧を取得
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| testdb             |
+--------------------+

mysql> quit

後ほど作成した「testdb」をDjangoの設定ファイル記述します。

dumpdataコマンド

dumpdataコマンドでは、データの出力と合わせて幾つかオプションを使用することができます。

Djangoの公式ドキュメントで詳しく載っています。

Django公式ドキュメント --dumpdata

SQLite3に保存されているデータの出力

まずはdumpdataコマンドを使用して、保存されているデータを出力してみます。


$ python3 manage.py dumpdata
[{"model": "auth.permission", "pk": 1, "fields": {"name": "Can add log entry",.....]

このように辞書形式となっていて、横一行となって保存されているデータが出力されます。

特定のモデルを指定してデータの出力

dumpdataコマンドのオプションとしてモデル名を与えると、そのモデル内に保存されているデータだけを出力することができます。

ここでは「app」というアプリ名の中にある「Todo」モデルを指定します。


$ python3 manage.py dumpdata app.Todo
[{"model": "app.todo", "pk": 1, "fields": {"title": "test1", "created_at": "2020-09-01"}}....]

出力されるデータに改行(インデント)を付ける

出力されるデータが一行では少し見難いこともあるので、オプションに改行(インデント)と改行の数を指定して中身を見やすくします。


$ python3 manage.py dumpdata app.Todo --indent 1
[
{
 "model": "app.todo",
 "pk": 1,
 "fields": {
  "title": "test1",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 2,
 "fields": {
  "title": "test2",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 3,
 "fields": {
  "title": "test3",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 4,
 "fields": {
  "title": "test4",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 5,
 "fields": {
  "title": "test5",
  "created_at": "2020-09-01"
 }
}
]

5つのTodoリストが保存されていることが分かります。

管理者のテーブルも確認してみます。


$ python3 manage.py dumpdata auth.user --indent 1
[
{
 "model": "auth.user",
 "pk": 1,
 "fields": {
  "password": "********",
  "last_login": null,
  "is_superuser": true,
  "username": "admin",
  "first_name": "",
  "last_name": "",
  "email": "admin@sample.com",
  "is_staff": true,
  "is_active": true,
  "date_joined": "2020-09-01T03:25:07.308Z",
  "groups": [],
  "user_permissions": []
 }
}
]

管理者もしっかり登録されています。

データをファイルへ書き込み

SQLiteに保存されているデータを確認することが出来たので、デフォルトのフォーマット形式である「json」ファイルに書き込んでいきたいと思います。

書き込むファイル名は、「db_chenge.json」として作成します。


$ python3 manage.py dumpdata > db_chenge.json

そうするとカレントディレクトリにファイルがあることが確認できます。


$ ls
app  config  db.sqlite3  db_chenge.json  manage.py

データベースの切り替え(SQLite3からMySQL)

さきほど作成したMySQLのデータベースを設定するために、設定ファイル「settings.py」を編集します。

# config/settings.py

...


""" SQLite3
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
"""

# MySQL
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testdb',  # db名
        'USER': 'root',
        'PASSWORD': 'パスワード',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

設定したら、マイグレーションを実行します。


$ python3 manage.py migrate

これでMySQLへと置き換わったデータベースのテーブルが作成されたので、先ほど書き込んだjsonファイルを読み込ませるだけです。

loaddataコマンド

Django公式ドキュメント --loaddata

loaddataコマンドにも幾つかオプションがありますが、割愛してデータを読み込んでいきます。


$ python3 manage.py loaddata db_chenge.json
Installed 41 object(s) from 1 fixture(s)

これだけで、データベース間でのデータの移動をすることができました。

実際にデータが保存されているか「dumpdata」コマンドで確認していきます。

まずは管理者が登録されているか確認

$ python3 manage.py dumpdata auth.user --indent 1
[
{
 "model": "auth.user",
 "pk": 1,
 "fields": {
  "password": "******",
  "last_login": null,
  "is_superuser": true,
  "username": "admin",
  "first_name": "",
  "last_name": "",
  "email": "admin@sample.com",
  "is_staff": true,
  "is_active": true,
  "date_joined": "2020-09-01T03:25:07.308Z",
  "groups": [],
  "user_permissions": []
 }
}
]

Todoモデルのデータが保存されているか確認


$ python3 manage.py dumpdata app.Todo --indent 1
[
{
 "model": "app.todo",
 "pk": 1,
 "fields": {
  "title": "test1",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 2,
 "fields": {
  "title": "test2",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 3,
 "fields": {
  "title": "test3",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 4,
 "fields": {
  "title": "test4",
  "created_at": "2020-09-01"
 }
},
{
 "model": "app.todo",
 "pk": 5,
 "fields": {
  "title": "test5",
  "created_at": "2020-09-01"
 }
}
]

しっかりデータは移動されているようですが、気になる方はサーバーを起動して管理画面を確認することをお勧めします。

特定のモデル内のデータを移動させたい場合は、jsonファイルに書き込む際にオプション指定することでデータを取り出すことができるので非常に便利ですね。

それでは以上となります。

最後までご覧いただきありがとうございました。

一覧へ戻る