質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1453閲覧

docker上のmysqlへホストのpythonからアクセスする方法

fia

総合スコア57

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/03/12 00:16

編集2023/03/12 02:34

実現したいこと

docker(ubuntuイメージ)上のmysqlにホスト(Windows)で動かしたpythonからアクセスしたです。
いろいろ調べたのですが、解決できないため、ご教授お願い致します。

前提

docker上のmysqlを構築済みでポートの3306も開いています。
dockerは、Docker Desktopを使用し、実行はコマンドプロンプトからおこなっています。
コンテナ作成時は以下のコマンドを実行しています。

$docker run --name db -p 3306:3306 -it ubuntu bash

mysqlは以下のコマンドで構築しています。
その後作成したユーザーでデータベースとテーブルを作成しています。

$sudo apt install mysql-server $sudo service mysql start $sudo mysql $CREATE USER 'xxx'@'localhost' IDENTIFIED BY 'xxx';

ホスト(Windows)で動かしたpythonが以下のエラーになり接続できていない状況です。

バージョン
mysql = Server version: 8.0.32-0ubuntu0.22.04.2 (Ubuntu)
ホスト = Windows10
python = 3.9
mysql-connector-python = 8.0.32

エラー

Traceback (most recent call last): File "D:\connect_db.py", line 14, in <module> main() File "D:\\connect_db.py", line 6, in main conn=mysql.connector.connect(host="127.0.0.1", port=3306, database='xxx', user='xxx', password='xxxx') File "D:\python\lib\site-packages\mysql\connector\pooling.py", line 293, in connect return CMySQLConnection(*args, **kwargs) File "D:\python\lib\site-packages\mysql\connector\connection_cext.py", line 118, in __init__ self.connect(**kwargs) File "D:\python\lib\site-packages\mysql\connector\abstracts.py", line 1178, in connect self._open_connection() File "D:\python\lib\site-packages\mysql\connector\connection_cext.py", line 293, in _open_connection raise get_mysql_exception( mysql.connector.errors.OperationalError: 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

該当のソースコード

python

1import mysql.connector 2 3def main(): 4 5 6 conn=mysql.connector.connect(host="127.0.0.1", port=3306, database='portfolio', user='fia_user', password='4dpIu@8Mjbg') 7 cur = conn.cursor() 8 cur.close() 9 conn.close() 10 11 12 13if __name__=='__main__': 14 main()

試したこと

docker側
ポートが開いてることの確認

$ss -atn State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 70 127.0.0.1:33060 0.0.0.0:* LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*

mysqlのconnect_timeoutを30に変更

mysql> SHOW GLOBAL VARIABLES LIKE '%timeout%'; +-----------------------------------+----------+ | Variable_name | Value | +-----------------------------------+----------+ | connect_timeout | 30 | | delayed_insert_timeout | 300 | | have_statement_timeout | YES | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | | lock_wait_timeout | 31536000 | | mysqlx_connect_timeout | 30 | | mysqlx_idle_worker_thread_timeout | 60 | | mysqlx_interactive_timeout | 28800 | | mysqlx_port_open_timeout | 0 | | mysqlx_read_timeout | 30 | | mysqlx_wait_timeout | 28800 | | mysqlx_write_timeout | 60 | | net_read_timeout | 30 | | net_write_timeout | 60 | | replica_net_timeout | 60 | | rpl_stop_replica_timeout | 31536000 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 60 | | ssl_session_cache_timeout | 300 | | wait_timeout | 28800 | +-----------------------------------+----------+

ホスト側
3306への疎通確認

$Test-NetConnection localhost -port 3306 ComputerName : localhost RemoteAddress : ::1 RemotePort : 3306 InterfaceAlias : Loopback Pseudo-Interface 1 SourceAddress : ::1 TcpTestSucceeded : True
$netstat アクティブな接続 プロトコル ローカル アドレス 外部アドレス 状態 TCP 127.0.0.1:3306 kubernetes:61074 TIME_WAIT TCP 127.0.0.1:3306 kubernetes:61081 TIME_WAIT TCP 127.0.0.1:3306 kubernetes:61083 TIME_WAIT TCP 127.0.0.1:3306 kubernetes:61085 TIME_WAIT TCP 127.0.0.1:3306 kubernetes:61087 TIME_WAIT

ほかに、pythonのコードをdocker内で実行したら動くことが確認できました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dameo

2023/03/12 01:11

どこからどうdockerを起動しているのかよく分かりません。 WSL2上のUbuntuからdockerを起動しているのでしょうか? それとも有料のdocker desktopですか? それともVirtualBox上のLinuxからdockerを起動していますか? 正確に記載してください。
yuma.inaura

2023/03/12 02:20

ポートマッピングしてますか?
fia

2023/03/12 02:35

追加の情報を記載致した。
dameo

2023/03/12 02:52

docker desktopはよく分かりません。失礼します。
fia

2023/03/12 17:24

教えていただいたサイトの手順で行えば接続できているようです。
jbpb0

2023/03/12 19:50

> 接続できているようです。 ・docker desktop側は接続できた状態そのまま ・pythonの「mysql.connector.connect」の設定を、windowsのsqlクライアントから接続できた設定に合わせる としたら、接続できますでしょうか?
fia

2023/03/12 21:35

Pythonの方でも接続できました。
jbpb0

2023/03/12 22:59

> Pythonの方でも接続できました。 その状態から下記を行ったら、どうなりますでしょうか? ・docker desktop側は質問者さんが作成したものを使うが、「-p 3306:3306」ではなく、接続できた時と同じ「-p 33306:3306」とする ・「mysql.connector.connect」の、「database」と「user」と「password」はdocker desktop側に合わせて質問に記載のものに変更し、「host」と「port」は接続できた時と同じまま変えない
fia

2023/03/13 03:37 編集

接続できませんでした。 jbpd0さんが教えてくださったもののを「-p 33306:3306」から「-p 3306:3306」にして実行すると接続できました。 今までの接続はrootユーザーで行っていましたが、ユーザー作成するときは'xxx'@'localhost'から'xxx'@'172.17.0.1'で作成すればmysql イメージなら接続できることができました。
jbpb0

2023/03/13 04:20

> 「-p 33306:3306」から「-p 3306:3306」にして実行すると接続できました。 ・docker desktopは「-p 33306:3306」で、「mysql.connector.connect」は「port=33306」では、接続できない ・docker desktopは「-p 3306:3306」で、「mysql.connector.connect」は「port=3306」では、接続できる ということですね 私が挙げた参考webページの手順で、sqlクライアントの代わりにpythonの「mysql.connector.connect」を使った場合は、上記の前者で接続できたのに、今回は前者でダメなのは不思議です (質問者さんの目的が達成できるのなら、どちらでもいいのですが)
fia

2023/03/13 05:02

おそらく、自分でインストールしたmysql と教えてくださった作成済みmysql イメージで何らかの設定が違うせいだと思います あまりスッキリしないですが、やりたいこと自体は達成できるので、これで進めたいと思います。 ありがとうございます
dameo

2023/03/13 09:12

そこまで出来たなら残りは分かりますよ。 問題1) docker buildやdocker commitなどのコマンドがなく、イメージになっていない(docker desktopでどう実施するのか不明) →コンテナを削除しない前提であれば無視できる 問題2) データベースの作成コマンドや権限設定の記述がない →動いてるなら本人だけは問題ない 問題3) ubuntuコンテナにインストールしたmysqlのlisten設定がループバックになっている →/etc/mysql/mysql.conf.d/mysqld.cnfで #bind-address = 127.0.0.1 bind-address = 0.0.0.0 他の人が再現出来るように書いておくと(対応は入っていますが)、 C:\...\> docker run -it --rm -p 3306:3306 ubuntu root@4aea1292eb3e:/# apt update && apt install -y mysql-server root@4aea1292eb3e:/# sed 's/^\(bind-address[^=]*\)= 127\.0\.0\.1/\1= 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf >/tmp/mysqld.cnf.$$ root@4aea1292eb3e:/# mv /tmp/mysqld.cnf.$$ /etc/mysql/mysql.conf.d/mysqld.cnf root@4aea1292eb3e:/# service mysql start root@4aea1292eb3e:/# mysql mysql> CREATE USER 'user'@'%' IDENTIFIED BY 'pass'; mysql> create database hoge character set=utf8mb4; mysql> grant all on hoge.* to 'user'@'%'; 別端末から C:\...\>python -m venv env C:\...\>.\env\Scripts\activate (env)C:\...\>pip install -U pip setuptools (env)C:\...\>pip install mysql-connector-python (env)C:\...\>type hoge.py import mysql.connector with mysql.connector.connect(host='localhost', port=3306, database='hoge', user='user', password='pass') as conn: with conn.cursor() as cur: pass (env)C:\...\>python hoge.py (env)C:\...\>deactivate C:\...\> で動くかと思います。 ※コンテナが終了し破棄されると、イメージは保存されないので、最初から実施しないと動きません。 スッキリしないとか言うくらいなら、他の人がモヤモヤしない(コメント欄が必要のない)質問をしましょう。
guest

回答1

0

自己解決

DockerをDocker Hubから作成済みのmysqlイメージを持ってきたものを使用する
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=root -p 33306:3306 mysql

ユーザーを作成するときは以下のコマンドを使う
CREATE USER 'user'@'172.17.0.1' IDENTIFIED BY 'password'

投稿2023/03/13 05:12

fia

総合スコア57

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問