円安の影響でherokuの最安料金でさえ貧乏学生が支払う金額としてはキツくなってきたので移行を決意。この時の覚え書き。(MySQLスキーマ変更あたりは泥臭い処理をしてしまっている)
注意) 自分の操作より、もっと良いコマンド操作があると思います。
herokuから PostgreSQLデータをダンプ
dockerでPostgreSQLを起動
- pg_dumpのためだけにdbを生ダウンロードしたくなかったので、dockerでpostgresを作りました。
(参考リンク🔽)
postgresのdocker コンテナ作成
docker run --name postgres -e POSTGRES_PASSWORD=617e330ed35242e6dca3dc8b0c5629efb0f9a90ecdec07ddc2e532d617ddd8e1 -e POSTGRES_INITDB_ARGS="--encoding=UTF8 --no-locale" -e TZ=Asia/Tokyo -p 5432:5432 -v $PWD:/my_data -d postgres
herokuのPostgresSQLデータをローカルにダンプ
(参考リンク🔽)
アプリ名検索 & herokuのデータベース情報を取得
heroku apps
heroku pg:credentials:url --app (アプリ名)
dockerのPostgreSQLに入る
docker exec -it postgres /bin/bash
データ & スキーマをダンプ
pg_dump --no-acl --no-owner -h (--.amazonaws.com) -U (ユーザ名) -v -a -(データベース名) > /my_data/postgres/(ダンプファイル名)
pg_dump --no-acl --no-owner -h (--.amazonaws.com) -U (ユーザ名) -v --schema-only -(データベース名) > /my_data/postgres/(ダンプファイル名)
- ()の部分は 適当な値を入れる
- コマンド実行ごとに パスワードを聞かれる
- ダンプファイルをdocker外部に取り出したい場合、 『/my_data/欲しい場所』 にする。(PostgreSQLのコンテナ起動時に/my_dataをdocker外部のディレクトリに反映する設定をしているため)
MySQLに移行
ファイル内容
自分はMySQLに接続する側も dockerで連携させた。以下が dockerの例
docker-compose.yml
services:
db:
build:
dockerfile: ./Dockerfile_sql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: user
DB_USERNAME: user
MYSQL_PASSWORD: user
MYSQL_DATABASE: user
ports:
- 3306:3306
volumes:
- ./mysql:/var/lib/mysql
- ./postgres:/my_data #移行用データ保存元
api:
build:
content: .
dockerfile: ./Dockerfile
ports:
- 8000:8000
volumes:
- .:/mysite
tty: true # コンテナの永続(必要か分からないけど)
depends_on:
- db
Dockerfile
FROM python
ENV PYTHONUNBUFFERED 1
RUN mkdir /mysite
# docker内部で実行スタート場所を mysiteディレクトリに
WORKDIR /mysite
#現在のディレクトリ構成を dockerのmysiteフォルダに反映
Add . /mysite
Dockerfile_sql
FROM mysql:5.7
RUN mkdir /my_data
# postgresに入れた シェルファイルでmysql設定を変更
Add /postgres/change_mysql_utf.sh /my_data/
RUN sh my_data/change_mysql_utf.sh
change_mysql_utf.sh
#! /bin/sh
## utf8に変更
sed -i -e "s/\[mysqld\]/\[mysqld\]\ncharacter-set-server=utf8\n/g" ../etc/my.cnf
sed -i -e "s/\[client\]/\[client\]\ndefault-character-set=utf8\n/g" ../etc/my.cnf
dockerのMySQL起動
- apiを起動することで、db側も同時に立ち上げる
- mysqlコンテナIDは
docker ps
で 『(現在フォルダ名)-db-』 と書かれた左側
docker-compose run api
docker exec -it mysqlのコンテナID /bin/bash
(+a)エラー時など?
参考
mysqlフォルダの初期化
rm -r ./mysql
mkdir ./mysql
docker compose up --build -d
- --buildで docker image生成から行う(しなくて大丈夫かも?)
buildしすぎた時の 実行停止 & キャッシュ削除?(良いのか分からないけどメモ)
docker-compose down --remove-orphans
- upと runの違いがわかってないので用調べ ↑
Postgresのデータを微調整
以下、ひっかかった時に参考にしたサイト。これを利用し自作ファイルで微調整した。
基本処理
- 自分はめんどくさくなって、schemaのtable宣言以外(ALTER TABLE関係)も徹底削除した。DB定義をよく変更していた方には良くないかも...
publicについて
timestamp関係
まとめサイト的
おまけ?(自作の変換コード)
MySQL操作
- mysqlコンテナ内部でmysqlにログイン
mysql -u root -proot -h 127.0.0.1 -P 3306
- rootユーザでしかログインできなかった
- パスワード、ポート番号などはdocker-compose参考
その他のポイント?
- djangoの runserverなどは 0.0.0.0を利用して動かさないとダメ
- 例
python manage.py runserver 0.0.0.0:8000
uvicorn main:app --reload --host 0.0.0.0 --port 8000
- fastAPIの場合、URLは
"mysql://root:root@db:3306/user?charset=utf8"
- host名は docker-composeで作成した場合、サービス名で接続可能らしい?
自分のディレクトリ構成
- docker-compose.yml
- Dockerfile
- Dockerfile_sql
- * SQL変更pythonファイル
- postgres
- change_mysql_utf.sh
- * ダンプデータ
- data
- * SQLのテーブル別tsvファイル
(自分の実際の環境設定と変更している面もあるので、エラーが見つかった場合質問していただけると誤りに気付けて助かります。)