【MySQL・Windows・Docker】MySQLコンテナに dumpファイルをインポートする方法

database システム開発

<環境>
OS : Windows
DB : MySQL
仮想化ツール : Docker
コマンドラインシェル : PowerShell / git bash / コマンドプロンプト

Windows 上で起動している MySQL のコンテナに dump ファイルをインポートする方法を調べてると、結構一筋縄では行かなかった。

dumpファイルをエクスポート:PowerShellコマンド(コンテナの外から実行)

コンテナの外からダンプを取る場合、コマンドはこんな感じです。

MySQL のコンテナ名は「mysql」です。

docker-compose exec mysql mysqldump --user=root --password=password myapp01 > dump_file_20221119.sql

自身の環境で実行する時、「–user」「–password」を適当に読み替えてください。
また、スキーマは「myapp01」を指定しています。

コマンドを実行すると、dump_file_20221119.sql というファイルが出力されます。
ここまでは順調。

dumpファイルをインポート

PowerShellコマンド(コンテナの外から実行)【エラー】

通常通りインポートコマンドを実行してみる。

docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql

実行結果は、こんな感じです。

PS C:\kaki\work> docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql
発生場所 行:1 文字:90
+ ... ql --host=localhost --user=root --password=password myapp01 < dump_fi ...
+                                                                 ~
演算子 '<' は、今後の使用のために予約されています。
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RedirectionNotSupported

PowerShell では、「<」を含むコマンドは使えないみたいです。

エスケープさせるにはどうすれば? と思って調べてみても、「<」はエスケープ出来ないみたいです。

(参考)
特殊文字について – PowerShell | Microsoft Learn

試しに「`<」「”<“」で実行してみましたが、どれも上手く行きませんでした。

PowerShell スクリプトを実行【エラー】

PowerShell スクリプトを作成し、それを実行したら上手くいくのでは?
と考えて実験。

「dump-import.ps1」というファイルを作成して実行してみました。
ファイルの内容は、こんな感じ。

dump-import.ps1

Write-Host "dump importing..."

# docker-compose exec mysql bash
docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql

実行コマンドは以下。

PowerShell -ExecutionPolicy RemoteSigned .\dump-import.ps1

実行結果

PS C:\kaki\work\tmp> PowerShell -ExecutionPolicy RemoteSigned .\dump-import.ps1
発生場所 C:\kaki\work\dump-import.ps1:4 文字:90
+ ... ql --host=localhost --user=root --password=password myapp01 < dump_fi ...
+                                                                 ~
演算子 '<' は、今後の使用のために予約されています。
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported

結果、変わらず。

ちなみに、「docker-compose exec mysql bash」が正常に実行できる事は確認出来ました。

git bash を使う【エラー】

PowerShell を使う事を諦め、git bash で実験。

実行結果

$ docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

「winpty」を使えばいいらしい。

良く分からないが、コマンドの先頭に「winpty」を付けて実行するといいそうな。

(参考)
the input device is not a TTY. If you are using mintty, try prefixing the command with ‘winpty’ · Issue #2888 · vercel/hyper

という事で、再び実行。

$ winpty docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql
stdin is not a tty

「stdin is not a tty」という無常のメッセージが。

調べてみると、こんなのが見つかった。

docker-compose on wsl: stdin is not a tty · Issue #166 · rprichard/winpty

It’s a long standing issue with Docker.
The way it does terminal detection only works with cmd.exe and powershell.exe at the moment. Any third-party terminal breaks that detection and gives the message.

どうやら、Docker コマンドを実行する場合は、先頭に winpty を使用できず、powershell と cmd を直接使わないといけないみたい。(Windows の場合)

ちなみに「winpty」は、こういうものらしいです。

[Git Bash] winpty コマンドについて調べてみた | MSeeeeN | 大阪発 IT メディア by MSEN

winpty コマンドは、 Windows のコンソールプログラムと UNIX の仮想端末を通信させるためのインタフェース です。

コマンドプロンプトを使う【エラー】

という事で、cmd で実験。

C:\kaki\work>docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

先頭に「winpty」を付けて実験してみる。

C:\kaki\work\ryuki-prd>winpty docker-compose exec mysql mysql --host=localhost --user=root --password=password myapp01 < dump_file_20221119.sql
'winpty' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

ダメでした。

コンテナの内部から実行【成功(ただし、効率悪い)】

コンテナの中に入ってインポートコマンドを実行。

ホストとの共有フォルダが無い場合、volumes を編集する必要がある。
編集例、こんな感じ。

docker-compose.yml

  mysql:
    image: mysql:5.7

#(中略)

    volumes:
      - db-data:/var/lib/mysql
      - ./containers/tmp:/tmp  # ホストとの共有ボリュームを追加

エクスポートしたダンプファイルを「containers/tmp」に保存し、mysql コンテナにログイン。
コンテナ内の「/tmp」ディレクトリにて、インポートコマンドを実行。

欠点:コンテナをビルドし直す必要がある。面倒。

そもそもダンプファイルをインポートするだけで docker-compose.yml を編集してコンテナをビルドし直すとか、明らかに手順がおかしいだろ。

MySQL Workbench を使う

という事で、Windows 上で起動している MySQL のコンテナに dump ファイルをインポートするのは、MySQL Workbench が一番良いのではないでしょうか。

ちなみに、上記のコマンドラインで実行した dmpファイルをインポートすると、文字コード絡みの面倒くさそうなエラーが発生したので、エクスポートも MySQL Workbench を使った方が良さそうです。

MySQL Workbench:エクスポート

1.Server → Data Export

sqlworkbench01

2.Start Export

エクスポートするスキーマを選択。(図では「myapp01」)

Export Self-Contained File を選択。
(これを選択しない場合、テーブルごとに dmpファイルが作成され、ファイル数が非常に多くなります)

出力ファイル名を設定。

その後、「Start Export」

sqlworkbench02

3.エクスポート完了

sqlworkbench03

MySQL Workbench:インポート

1.既存のスキーマを削除

「myapp01」をフルインポートするので、既存のスキーマを削除。

sqlworkbench04

2.Create Schema

削除したスキーマを再作成。(図では「myapp01」)

sqlworkbench05

Name を入力後、「Apply」

sqlworkbench06

Algorithm、Lock Type はデフォルト設定でOKです。
sqlworkbench07

スキーマが作成されます。
sqlworkbench08

3.Server → Data Import

sqlworkbench09

4.Start Import

「Import from Self-Contained File」を選択し、エクスポートファイルを指定。

「Default Target Schema」にて、対象となるスキーマを指定。

その後、「Start Import」

sqlworkbench10

5.インポート完了

sqlworkbench11

雑感

PowerShell で「<」が使えるようになってくれないかな。

コメント

タイトルとURLをコピーしました