【Heroku・Django】リモートサーバーにあるデータやファイルをローカル側に移行・コピー(転送)


投稿日 2022年6月14日 >> 更新日 2023年3月1日

概要

この記事はHerokuでDjangoアプリを運用していてデータベースに保存されたデータや運用仮定で作成されたファイルをローカル環境に移行もしくわコピー(転送)するといった内容です。

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

実行環境
Windows Subsystem for Linux
heroku 7.60.2
Python 3.6.9
pip 21.3.1
使用ライブラリ ライセンス
Django==3.2.13 BSD

djangoの「dumpdata」コマンドでデータベースに保存されているデータを取得する

djangoの「dumpdata」コマンドを使うことで各々のデータベースからデータを取得できます。

例えば「todo」と言うアプリからモデル「post」というテーブルに保存されているデータを取得したいといった場合は以下のように打ちます。

$ python3 manage.py dumpdata todo.post
[{"model": "todo.post", "pk": 3, "fields": {"title": "ローカル1", "created_at": "2022-06-14T03:25:50.214Z"}}, {"model": "todo.post", "pk": 4, "fields": {"title": "ローカル2", "created_at": "2022-06-14T03:25:57.052Z"}}, {"model": "todo.post", "pk": 5, "fields": {"title": "ローカル3", "created_at": "2022-06-14T03:26:04.975Z"}}]

各項目ごとにインデントされたデータを取得したい場合はオプションを付けます。

※「--indent 1」の数字は改行された後の空白行です。

$ python3 manage.py dumpdata todo.post --indent 1
[
{
 "model": "todo.post",
 "pk": 3,
 "fields": {
  "title": "ローカル1",
  "created_at": "2022-06-14T03:25:50.214Z"
 }
},
{
 "model": "todo.post",
 "pk": 4,
 "fields": {
  "title": "ローカル2",
  "created_at": "2022-06-14T03:25:57.052Z"
 }
},
{
 "model": "todo.post",
 "pk": 5,
 "fields": {
  "title": "ローカル3",
  "created_at": "2022-06-14T03:26:04.975Z"
 }
}
]

この「dumpdata」コマンドをherokuのリモートサーバーで実行することによってデータを取得できます。

herokuのリモートサーバーでコマンドを使用するには、「heroku run ...」コマンドを実行します。例えばリモートサーバーにあるアプリディレクトリの一覧を確認したい場合は以下のように打ちます。

※「git push heroku master」で送信されたファイル群とその他

$ heroku run ls
Running ls on ⬢ immense-crag-00760... up, run.9215 (Free)
manage.py  Procfile  project  requirements.txt  runtime.txt  staticfiles  todo

Linuxの「ls」コマンドによってディレクトリ内のファイルを一覧表示しています。上記のように「heroku run」に続いて「dumpdata」コマンドを実行するとherokuのリモートサーバー上にあるデータベースから、保存されているデータを取得することができます。

ではアプリの「todo」からモデルの「post」に保存されたデータを取得します。

$ heroku run python3 manage.py dumpdata todo.post
Running python3 manage.py dumpdata todo.post on ⬢ immense-crag-00760... up, run.7421 (Free)
[{"model": "todo.post", "pk": 1, "fields": {"title": "リモート1", "created_at": "2022-06-14T04:23:22.844Z"}}, {"model": "todo.post", "pk": 2, "fields": {"title": "リモート2", "created_at": "2022-06-14T04:23:31.385Z"}}, {"model": "todo.post", "pk": 3, "fields": {"title": "リモート3", "created_at": "2022-06-14T04:23:35.317Z"}}]

上記のコマンドで実行されたデータを、大なり「>」記号を使ってローカル環境に「dumpdata.json」としてファイルに書き込みます。

$ heroku run python3 manage.py dumpdata todo.post > dumpdata.json
Running python3 manage.py dumpdata todo.post on immense-crag-00760... up, run.7867 (Free)

これでローカル環境に「dumpdata.json」ファイルが作成されました。

$ ls
... dumpdata.json ...

ではローカル環境の「todo」アプリにある「post」モデル内のデータを移行させます。

まずは「migratge」コマンドを使って一時的にtodoアプリ内のpostモデルを削除します。

$ python3 manage.py migrate todo zero
Operations to perform:
  Unapply all migrations: todo
Running migrations:
  Rendering model states... DONE
  Unapplying todo.0001_initial... OK

再び「migrate」コマンドを実行して初期化します。

$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, todo
Running migrations:
  Applying todo.0001_initial... OK

todoアプリのデータベースは初期化されたので、djangoの「loaddata」コマンドを実行して「dumpdata.json」に書き込まれたデータをローカル環境内のデータベースに復元します。

$ python3 manage.py loaddata dumpdata.json
Installed 3 object(s) from 1 fixture(s)

「dumpdata」コマンドでアプリ内のデータを確認してみると、リモートサーバーで作成されたデータがローカル環境内のデータベースに保存されていることがわかります。

$ python3 manage.py dumpdata todo.post
[{"model": "todo.post", "pk": 1, "fields": {"title": "リモート1", "created_at": "2022-06-14T04:23:22.844Z"}}, {"model": "todo.post", "pk": 2, "fields": {"title": "リモート2", "created_at": "2022-06-14T04:23:31.385Z"}}, {"model": "todo.post", "pk": 3, "fields": {"title": "リモート3", "created_at": "2022-06-14T04:23:35.317Z"}}]

ローカル環境下のデータをリモートサーバーのデータベースに保存したい場合は、ローカルで「dumpdata.json」を作成し、そのファイルを除外せずにそのままコミットしてリモートに送信してしまえば可能です。

※些細な例

$ ls
Procfile  db.sqlite3  dumpdata.json  manage.py project  requirements.txt  todo venv

$ git add .

$ git commit -m 'dumpdata.json push'
[master 8d7839e] dumpdata.json push
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 dumpdata.json

$ git push heroku master
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 520 bytes | 104.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
...

$ heroku run ls
Running ls on ⬢ immense-crag-00760... up, run.9388 (Free)
dumpdata.json  manage.py  Procfile  project  requirements.txt  runtime.txt  staticfiles  todo

$ heroku run python3 manage.py migrate todo zero
Running python3 manage.py migrate todo zero on ⬢ immense-crag-00760... up, run.7715 (Free)
Operations to perform:
  Unapply all migrations: todo
Running migrations:
  Rendering model states... DONE
  Unapplying todo.0001_initial... OK

$ heroku run python3 manage.py migrate
Running python3 manage.py migrate on ⬢ immense-crag-00760... up, run.4982 (Free)
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, todo
Running migrations:
  Applying todo.0001_initial... OK

$ heroku run python3 manage.py loaddata dumpdata.json
Running python3 manage.py loaddata dumpdata.json on ⬢ immense-crag-00760... up, run.4210 (Free)
Installed 3 object(s) from 1 fixture(s)

Herokuのリモートサーバーに配置されているファイルをローカル環境にコピー(転送)する。

herokuのリモートサーバーで作成されたファイルをローカル環境へコピーすることができます。

例えばローカルレポジトリをherokuのリモート先にプッシュされた際に「runtime.txt」というPythonのバージョン情報が格納されたファイルが作成されます。このファイルを「heroku ps:copy ..」コマンドを使用してローカルにコピーします。

ローカル環境及びリモートサーバーのディレクトリにあるファイル一覧を確認します。

$ ls
Procfile  db.sqlite3  dumpdata.json  manage.py  project  requirements.txt  todo  venv

$ heroku run ls
Running ls on ⬢ immense-crag-00760... up, run.9036 (Free)
dumpdata.json  manage.py  Procfile  project  requirements.txt  runtime.txt  staticfiles  todo

リモートサーバー側にだけ「runtime.txt」ファイルがあることを確認できたら、コピーコマンドを実行します。

$ heroku ps:copy runtime.txt
Copying runtime.txt to runtime.txt
Establishing credentials... done
Connecting to web.1 on ⬢ immense-crag-00760...
Downloading... ████████████████████████▏  100% 00:00

$ ls
Procfile  db.sqlite3  dumpdata.json  manage.py  project  requirements.txt  runtime.txt  todo  venv

コピーされました。コピー先のファイル名を変更したい場合は、オプションの「-o」を付けた後にコピー先のファイル名を指定します。

$ heroku ps:copy -o run_time.txt runtime.txt
Copying runtime.txt to run_time.txt
Establishing credentials... done
Connecting to web.1 on ⬢ immense-crag-00760...
Downloading... ████████████████████████▏  100% 00:00

$ ls
Procfile  db.sqlite3  dumpdata.json  manage.py  project  requirements.txt  run_time.txt  todo  venv

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

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