以前の記事でSequelを使ってMS Accessへと接続できることが分かりました。
ただ、残念ながらテーブル名やカラム名が日本語になっていることがあるため、その場合はどうなるかを試してみました。
環境
また、MS Accessに日本語サンプル
テーブルを以下の構造で用意します。半角カタカナを使っています。
カラム名 | 型 |
---|---|
ID | オートナンバー |
名前 | テキスト |
コメント | テキスト |
なお、データベースファイル名は日本語でも接続できました。
検証
事前準備
今回のコードの基本形は以下の通りです。TableNameテーブルより、ID=1のデータを取得し、col1列を表示します。
ACCDB_PATH = '//127.0.0.1/db/Sample.accdb' OLEDB_PROVIDER = 'Microsoft.ACE.OLEDB.12.0' ODBC_DRIVER = '{Microsoft Access Driver (*.mdb, *.accdb)}' db = Sequel.ado(conn_string: "Provider=#{OLEDB_PROVIDER};Data Source=#{ACCDB_PATH}") ds = db[:TableName].select(:col1, :col2).where(ID: :$n) r = ds.prepare(:first).call(n: 1) p r[:col1]
Sequelではテーブル名やカラム名をシンボルで指定するため、テーブル名やカラム名が日本語のMS Accessに対し、以下のコードでカラム名とエンコーディングを取得してみます。
r.each do |k, v| p k #=> `:名前` or `:コメント` p k.encoding #=> #<Encoding:Windows-31J> end
カラム名は日本語のシンボルで、エンコーディングがEncoding:Windows-31J
のようです。
次に日本語シンボルをEncoding:UTF-8
のものとEncoding:Windows-31J
のものを作ってみました。
key = '名前'.force_encoding('cp932').to_sym p key.encoding #=> <Encoding:Windows-31J> p Symbol.all_symbols.select{|e| e == key}.count #=> `1`となり、登録されている ## 日本語シンボル(UTF-8) p :名前.encoding #=> #<Encoding:UTF-8> p Symbol.all_symbols.select{|e| e == :名前}.count #=> `1`となり、登録されている
シンボルとして登録されていて、エンコーディングも指定された通りのようです。
日本語シンボルを使ったデータ取得
基本形を上記のシンボルに変えて、日本語カラムからのデータ取得を試してみました。
ds1 = db[:日本語サンプル].select(:名前, :コメント).where(ID: :$n) r1 = ds1.prepare(:first).call(n: 1) ### 取得できたかを確認: 取得できている p r1 #=> {:名前=>"ほげ", :コメント=>"ホゲ"} ### 事前に用意したシンボルで、特定の列を取得してみる p r1[key] #=> nil (CP932のシンボルで列を取得できない) p r1[:名前] #=> nil (UTF-8のシンボルで列を取得できない)
ソースコードのコメント通り、どちらのシンボルを使っても日本語カラムからデータを取得することができませんでした。
Sequelではエンコードを変更していなさそうなので、これ以上追求することはやめておきました。
MSSQL-Server/ruby-gem sequel: How to read UTF-8 values? - Stack Overflow
エイリアスを使ったデータ取得
Sequelではselectメソッドを使うときに:名前___name
としてエイリアスを付けることができるため、日本語カラム名に英語のエイリアスを付けて試してみました。
ds2 = db[:日本語サンプル].select(:名前___name, :コメント___comment).where(ID: :$n) r2 = ds2.prepare(:first).call(n: 1) ### 取得できたかを確認: 取得できている p r2 #=> {:name=>"ほげ", :comment=>"ホゲ"} # エイリアスで、特定の列を取得してみる p r2[:name] #=> "ほげ" p r2[:comment] #=> "ホゲ"
コメント通り、取得することができました。
ただ、本当にこれでいいのかという気もするので、何かあればご指摘ください。
検証時のコード
Gistに上げました。
Ruby + Sequelを使って、テーブル名やカラム名が日本語のMS Accessからデータを抽出する
データベースファイルはSinatraToMSAccess-SampleのSample.accdb
を使いました。
thinkAmi/SinatraToMSAccess-Sample · GitHub
その他
プリペアドステートメント
以下のドキュメントが参考になりました。
- sequel/doc/prepared_statements.rdoc at master · jeremyevans/sequel · GitHub
- prepare method - Sequel::Dataset
- ruby - How do I create a prepared insert statement in Sequel? - Stack Overflow
filterメソッドとwhereメソッド
filterメソッドはwhereメソッドのエイリアスのようだったため、見慣れているwhereメソッドを使いました。
method filter - Sequel::Dataset