Python+SQLAlchemyを使用してMySQLデータベースにリモート接続するにはどうすればいいですか? 質問する

Python+SQLAlchemyを使用してMySQLデータベースにリモート接続するにはどうすればいいですか? 質問する

MySQL にリモートでアクセスするのが困難です。SSH トンネルを使用し、Python + SQLALchemy を使用してデータベース MySQL に接続したいと考えています。

コンソールで MySQL クライアントを使用し、「ptotocol=TCP」を指定すると、すべて正常になります。次のコマンドを使用します。

mysql -h localhost —protocol=TCP -u USER -p

SSH トンネルを介してリモート データベースにアクセスします。

しかし、Python + SQLAchemy を使用してデータベースに接続したい場合、そのようなオプションが見つかりません。—protocol=TCPそれ以外の場合は、ローカルの MySQL データベースに接続するしかありません。教えてください。SQLAlchemy を使用してそれを実行する方法はありますか。

ベストアンサー1

この問題に対する典型的な答えは127.0.0.1ホストのIPまたはホスト名「特別な名前」の代わりにlocalhostドキュメンテーション:

[...] Unix上の接続ローカルホストデフォルトではUnixソケットファイルを使用して作成される

以降:

Unixでは、MySQLプログラムはホスト名をローカルホスト特別に、他のネットワークベースのプログラムと比較して、予想とは異なる方法で実行されます。localhost への接続の場合、MySQL プログラムは Unix ソケット ファイルを使用してローカル サーバーに接続しようとします。これは、ポート番号を指定するために --port または -P オプションが指定されている場合でも発生します。クライアントがローカル サーバーに TCP/IP 接続を確立するようにするには、--host または -h を使用して、ホスト名の値 127.0.0.1、またはローカル サーバーの IP アドレスまたは名前を指定します。


しかし、この単純なトリックはあなたの場合には機能しないようですので、何らかの方法でTCP ソケットの使用。ご自身で説明されているように、mysqlコマンド ラインで呼び出す場合は、--protocol tcpオプションを使用します。

説明したようにここSQLAlchemyから、関連するオプション(ある場合)をURLオプションとしてドライバーに渡すことができます。またはキーワード引数を使用しますconnect_args

例えばpyMySQL のそのために設定したテスト システム (MariaDB 10.0.12、SQLAlchemy 0.9.8、PyMySQL 0.6.2) では、次の結果が得られました。

>>> engine = create_engine(
      "mysql+pymysql://sylvain:passwd@localhost/db?host=localhost?port=3306")
#                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
#                               Force TCP socket. Notice the two uses of `?`
#                               Normally URL options should use `?` and `&`  
#                               after that. But that doesn't work here (bug?)
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost:54164',)]

# Same result by using 127.0.0.1 instead of localhost: 
>>> engine = create_engine(
      "mysql+pymysql://sylvain:[email protected]/db?host=localhost?port=3306")
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost:54164',)]

# Alternatively, using connect_args:
>>> engine = create_engine("mysql+pymysql://sylvain:passwd@localhost/db",
                       connect_args= dict(host='localhost', port=3306))
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost:54353',)]

お気づきのとおり、どちらも TCP 接続を使用します (ホスト名の後のポート番号からそれがわかります)。一方、

>>> engine = create_engine(
      "mysql+pymysql://sylvain:passwd@localhost/db?unix_socket=/path/to/mysql.sock")
#                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#                               Specify the path to mysql.sock in
#                               the `unix_socket` option will force
#                               usage of a UNIX socket

>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost',)]

# Same result by using 127.0.0.1 instead of localhost: 
>>> engine = create_engine(
      "mysql+pymysql://sylvain:[email protected]/db?unix_socket=/path/to/mysql.sock")
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost',)]

# Alternatively, using connect_args:
>>> engine = create_engine("mysql+pymysql://sylvain:passwd@localhost/db",
                       connect_args= dict(unix_socket="/path/to/mysql.sock"))
>>> conn = engine.connect()
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall()
[('localhost',)]

以降のポートはありませんホスト名: これは UNIX ソケットです。

おすすめ記事