Ruby
MySQL
mysql2

何番煎じかよ!、rubyでmysql2を使いリモートのmysqlDBにSSH接続する話

やりたかった事

定期的に行うバッチ処理やメンテナンス作業とかなども

リモート(異なるマシン)に存在するMySQL DBに対し、少しずつ条件を変えながら合致するものを受け取って、それぞれ異なる処理を行う・・・みたいな時。

手動でSQLコマンド打ち込んで処理するのは面倒。
受け取ったデータに対する処理も自動化したい。

概要

net-ssh-getway を使って、MySQLサーバが存在するリモートに接続する。
接続をもとに

ソース

論より証拠 とか 型から入る みたいな話ですが

vagrantで作ったホストオンリー環境を参照し、総務省の自治体コードをベースにしたデータを参照し、
千葉市に属する自治体コードを持つのデータをすべて取ってくるというデモ的な処理を行っています

接続例
require 'mysql2'
require 'net/ssh/gateway'

gateway = Net::SSH::Gateway.new(
  '192.168.33.10',
  'vagrant',
  password: 'vagrant,
  port: 22,
  keys: ['~/.ssh/ssh-key']
)

gateway.open('127.0.0.1', 3306) do |local_port|

client = Mysql2::Client.new(host: '127.0.0.1', database: 'if_kaigoworks', username: 'normal_user', password: 'normal_user', port: local_port )


  results = client.query(" select * from city_list where state_code = '12' and city_code like('10%') ")
  results.each do |row|
    p row
  end


end

SSH接続の設定部分

ssh接続
gateway = Net::SSH::Gateway.new(
  '192.168.33.10',
  'vagrant',
  port: 22,
  keys: ['~/.ssh/ssh-key']
)

接続部分

接続部分
gateway.open('127.0.0.1', 3306) do |local_port|

client = Mysql2::Client.new(host: '127.0.0.1', database: 'if_kaigoworks', username: 'normal_user', password: 'normal_user', port: local_port )


  results = client.query(" select * from city_list where state_code = '12' and city_code like('10%') ")
  results.each do |row|
    p row
  end


end

こういう描き方をしても良い

接続だけ作って、他の部分で使うことも考える

接続をよそでも使いまわしたい
@client = nil
gateway.open('127.0.0.1', 3306) do |local_port|

client = Mysql2::Client.new(host: '127.0.0.1', database: 'if_kaigoworks', username: 'username', password: 'password', port: local_port )

@client = client

end

  results = @client.query(" select * from state_city_tags where state_code = '12' and city_code like('10%') ")

  results.each do |row|
    p row
  end

実施結果

sshのパスワードを求められるので、入力する。
正しければスクリプトが走り、MySQLサーバに接続しSQLが実行され

実施例
$ ruby mysql_connect.rb 
vagrant@192.168.33.10's password:
{"id"=>611, "state_code"=>"12", "city_code"=>"1002", "state_name"=>"千葉県", "city_name"=>"千葉市"}
{"id"=>612, "state_code"=>"12", "city_code"=>"1011", "state_name"=>"千葉県", "city_name"=>"千葉市中央区"}
{"id"=>613, "state_code"=>"12", "city_code"=>"1029", "state_name"=>"千葉県", "city_name"=>"千葉市花見川区"}
{"id"=>614, "state_code"=>"12", "city_code"=>"1037", "state_name"=>"千葉県", "city_name"=>"千葉市稲毛区"}
{"id"=>615, "state_code"=>"12", "city_code"=>"1045", "state_name"=>"千葉県", "city_name"=>"千葉市若葉区"}
{"id"=>616, "state_code"=>"12", "city_code"=>"1053", "state_name"=>"千葉県", "city_name"=>"千葉市緑区"}
{"id"=>617, "state_code"=>"12", "city_code"=>"1061", "state_name"=>"千葉県", "city_name"=>"千葉市美浜区"}

クエリの内容通り、state_codeが"12"(文字)かつ、city_codeが"10"で始まるレコードの一覧が取れた
(この場合、state_code="12"が千葉県で、city_code like('10%') が、千葉市の区分になる)

参考

RubyでSSHトンネル経由でサーバにアクセスする
http://qiita.com/yuku_t/items/03e2e507add1cd2e2a40

http://www.soumu.go.jp/denshijiti/code.html