Heroku Postgres12からRDS MySQL8にデータ移行する

2020年11月1日

Heroku

Heroku Postgres からデータを csv 形式でエクスポートし、RDS MySQL にインポートする機会があったので手順を残します。以下の記事で MySQL → Postgres について書きましたが、その逆バージョンです。

Heroku
RDS MySQL8からHeroku PostgreSQL12へデータ移行する

前回は、Rails アプリケーションを Heroku にデプロイする方法を紹介しました。 今回は Amazon RDS ...

続きを見る

目次

  1. Heroku Postgres からデータをエクスポート
  2. ローカルの Postgres にデータをインポート
  3. ローカルの Postgres から CSV をエクスポート
  4. RDS MySQL に csv データをインポート

Heroku Postgres からデータをエクスポート

Heroku Postgres からデータをエクスポートするには、管理画面からダウンロードする方法と Heroku CLI を使う方法があります。

バックアップをとり

heroku pg:backups:capture --app ${app_name}

最新のバックアップをダウンロードします

heroku pg:backups:download --output ~/Downloads/latest.dump --app ${app_name}

詳しくは Importing and Exporting Heroku Postgres Databases | Heroku Dev Center を参照。

ローカルの Postgres にデータをインポート

Heroku からエクスポートしたデータはバイナリで、テキストエディタで開くことはできません。ドキュメント によるとpg_restore コマンドでローカルの Postgres にインポートする必要があります。

ローカルの PostgreSQL は、今回は Docker で準備をします。以下のコマンドでエクスポートしたファイル latest.dump があるディレクトリ(今回は ~/Downloads)をボリュームをマウントして、PostgreSQL を起動します。

docker run -d --name my-postgres --rm -v ~/Downloads:/root/work -w /root/work -e POSTGRES_PASSWORD=password postgres:12-alpine

起動したら、コンテナに入ります。

docker exec -it my-postgres ash

ドキュメントにかかれているコマンドでダンプしたデータを読み込みます

pg_restore --verbose --clean --no-acl --no-owner -U postgres -d postgres latest.dump

pg_restore コマンドの詳細は pg_restore PostgreSQL 12 文章 を参照。

ローカルの Postgres から CSV をエクスポート

PostgreSQL コンテナに復元したデータを CSV でエクスポートします。

引き続きコンテナにて psql コマンドで Postgres にログインします

psql -U postgres -d postgres

CSV 形式でエクスポートするには COPY を使います。以下は users テーブルのデータを users.csv にエクスポートする例です。この後 MySQL へデータを移行するので、区切り文字はタブ、囲み文字はなし、NULL をバックスラッシュ N にしています。

\COPY users TO '/root/work/users.csv' WITH csv DELIMITER ',' NULL '\N' HEADER QUOTE '"' FORCE QUOTE *;

COPY について詳しくは COPY PostgreSQL 12 文章 を参照。

users テーブルのデータが csv で出力されました。ホストマシンの latest.dump があるディレクトリ(今回は ~/Downloads)から確認することができます。

~/Download/users.csv

id,email,created_at,updated_at
"2","foo@example.com","2020-11-01 04:52:24",\N
"1","bar@example.com","2020-11-01 04:35:53",\N

すべてのテーブルの csv 出力が終わったらコンテナを終了させます。

docker stop my-postgres

RDS MySQL に csv データをインポート

EC2 インスタンスから mysql コマンドで RDS MySQL に接続できる状態にして、csv ファイルを EC2 インスタンスに転送します。

転送したら MySQL にログインし、以下のコマンドで csv データをインポートします。

LOAD DATA LOCAL INFILE 'users.csv' INTO TABLE admin_users FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES;

LOAD DATA INFILE 構文について詳しくは MySQL :: MySQL 8.0 Reference Manual :: 13.2.7 LOAD DATA Statement を参照。

インポート後、warnings が出ていないか確認をします。出ていた場合は show warnings 構文で内容を確認したり、インポート後のデータがおかしくないか確認をします。

Query OK, 2 rows affected (0.01 sec)
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0

-技術ブログ
-