お茶漬けびより

"あなたに教わったことを、噛んでいるのですよ" 五等分の花嫁 7巻 「最後の試験が五月の場合」より

Python 3.6 から MySQL データベースへ SSH 接続を試みる

f:id:pickles-ochazuke:20171210160653j:plain

仕事中は、いろいろ書きたい記事を思いつくのですが、いざ書こうとするとネタが思いつかないことがよくあります。
メモ代わりにここに書きますが、カテゴリとしては、Python, MySQL, グラフ描画, ウィンドウハンドルを使った自動化。みたいな感じです。忘れないうちに書かないと……。

そうそう、Google Home を買ったので、それを使って遊んだりもしたい。今は、Python, MySQL が優先なので、そちらを身につけつつその間に Google Home について調べておこうかなと。

無駄話はこれぐらいにして、本題に入ります。
前回は、ローカル(PC 内に入っているデータベース(DB)への接続)な環境の話でしたが、今回は、ネットワーク上の DB への接続を試してみます。

以下を参考にしました。

blog.honjala.net

環境の準備

まずは、今回使うモジュールを落としてきます。

pip install sshtunnel

ちなみにモジュールは、Github に公開されています。

github.com

これで SSH 接続するための環境は出来ました。 次は、実際にコードを書いて接続します。

SSH 接続を試みる

以下のコードを実行すると、SSH 接続するためのポート番号(何のポート番号かは分かっていません……)が出力されます。

# -*- coding: utf-8 -*-
from sshtunnel import SSHTunnelForwarder
import mysql.connector

port_num = 22
with SSHTunnelForwarder(
    ('ip_address', port_num),
    ssh_username='user_name',
    ssh_password='user_pass',
    remote_bind_address=('127.0.0.1', 3306)
) as server:

print(server.local_bind_port)

ip_address には、接続したい DB がある IP アドレスを。port_num には、SSH 接続のポート番号を(通常は、22)。remote_bind_address には、DB がある IP アドレスとポート番号を指定するのですが、通常は、SSH 接続先にあると思うので、上記で問題ないと思います。

上手くいけば、ポート番号が表示されていると思います。 問題なければ SSH 接続が成功しています。with を使わずに open(), close() のような方法もあります。以下のようにして、接続します。

port_num = 22
server SSHTunnelForwarder(
    ('ip_address', port_num),
    ssh_username='user_name',
    ssh_password='user_pass',
    remote_bind_address=('127.0.0.1', 3306)
)
server.start()

# 処理

server.stop()

start()open()stop()close() の役割をしています。 では、次に出力したポート番号を使って DB へ接続します。 ここでは、前回使用したモジュール(mysql.connector)を使って接続しています。

前回 pickles-ochazuke.hatenablog.com

conn = mysql.connector.connect(
    host = 'localhost',
    port = server.local_bind_port,
    user = 'user_name',
    password = 'user_pass',
    database = 'db_name',
)

前回とほぼ変わりません。port のところに先ほど出力したポート番号を使っています。

おわり

以上です。とても簡単にできたと思います。

今回の SSH 接続の部分とは関係ありませんが、クエリを実行して、結果を取得する際に単純に受け取るとリストになると思います。一応これでも扱えるのですが、pandas のデータフレームというのを使うともっと便利に扱えるようになります。そこら辺も近いうちに書きたいと思います。