今回は、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
ここでは「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コマンドでは、データの出力と合わせて幾つかオプションを使用することができます。
Djangoの公式ドキュメントで詳しく載っています。
まずはdumpdataコマンドを使用して、保存されているデータを出力してみます。
$ python3 manage.py dumpdata
[{"model": "auth.permission", "pk": 1, "fields": {"name": "Can add log entry",.....]
このように辞書形式となっていて、横一行となってデータベースに保存されているデータが出力されます。
dumpdataコマンドの引数にアプリ名やモデル名を与えると、そのモデル内に保存されているデータだけを出力することができます。
引数を指定しなければデータベース内のデータ全て取得
$ python3 manage.py dumpdata
引数にアプリ名を与えるとアプリ内に保存されているデータを取得
$ python3 manage.py dumpdata app
引数にアプリ内のモデル名を与えるとモデルに限られたデータを取得
$ python3 manage.py dumpdata app.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"
}
}
]
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
さきほど作成した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コマンドを使用することで、jsonファイルに書き込んだデータを読み込む事ができます。
$ python3 manage.py loaddata db_chenge.json
Installed 41 object(s) from 1 fixture(s)
db_chenge.jsonにはデータベースに保存されたデータが書き込まれていますが、「app.todo」のようにモデルが指定されたデータが書き込まれている場合は以下のようにオプションを指定することができます。
loaddataコマンドの「--app」オプションにアプリ名とモデル名を指定します。
$ python3 manage.py loaddata --app app.todo db_chenge.json
これだけで、データベース間でのデータの移動をすることができました。
実際にデータが保存されているか「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ファイルに書き込む際にオプション指定することでデータを取り出すことができるので非常に便利ですね。
それでは以上となります。
最後までご覧いただきありがとうございました。