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

2020年11月1日

Heroku

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

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

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

続きを見る

目次

  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

-技術ブログ
-