SequelはJDBC以外ならいい
今度はSequelを試してみます。まずは、PostgreSQLにpostgres-prでつないでみます。
require 'rubygems' require 'sequel' DB = Sequel.postgres(:database => 'postgres', :user => 'postgres', :password => 'postgres') DB[:user_data].all.each do |user_data| puts "#{user_data[:user_id]} #{user_data[:user_account].kconv(Kconv::SJIS, Kconv::UTF8)}" end
モデルを作らなくても使えるのが、いいですね。
ActiveRecordの時と同様、kconvによるSJIS変換は無視してください。
JDBCだとこんな感じ。
require 'rubygems' require 'sequel' DB = Sequel.jdbc(:uri => 'jdbc:postgresql:postgres', :user => 'postgres', :password => 'postgres') Sequel::JDBC.load_driver('org.postgresql.Driver') DB["SELECT * FROM user_data"].all.each do |user_data| puts "#{user_data[:user_id]} #{user_data[:user_account].kconv(Kconv::SJIS, Kconv::UTF8)}" end; nil
JDBCドライバの登録が美しくありません。どなたか他に方法がありましたら教えてください。
また、JDBCの場合、シンボルによる表指定ができません。DB["SELECT * FROM user_data"].allは実行できても、DB[:user_data].allはエラーになります。
DB["SELECT * FROM user_data"].all # success DB[:user_data].all # fail
なぜかというと、JDBC接続時にDB[:user_data].allによって作られるSQL文が SELECT * FROM \"USER_DATA\" になってしまうからなんですよね。PostgreSQLでは表名の大文字と小文字を区別し、デフォルトでは小文字なので、USER_DATAなんて表はないということになってしまうのです。
sequel_core/sql.rbに以下のような記述がありました。
# This method quotes the given name with the SQL standard double quote. # It uppercases the name given to conform with the SQL standard. This # should be overridden by subclasses to provide quoting not matching the # SQL standard, such as backtick (used by MySQL and SQLite), or where # lowercase is the default for unquoted identifiers (PostgreSQL). # # If you are using a database such as Oracle that defaults to uppercase # but you are using lower case identifiers, you should override this # method to not upcase the name for those identifiers. def quoted_identifier(name) "\"#{name.to_s.upcase}\"" end
これが原因らしいぞ。デフォルトで大文字にしちゃうわけね。adapters/postgres.rbではquoted_identifierをオーバーライドしてupcaseを消し去るのでDB[:user_data].allはエラーにならないが、JDBCだと大文字の表を探しちゃうわけか。
というわけで、回避策としては、シンボルを使わないか、Sequel::JDBC::Datasetを書き換えるかです。後者だと、以下のようになります。
require 'rubygems' require 'sequel' module Sequel module JDBC class Dataset < Sequel::Dataset def quoted_identifier(name) "\"#{name.to_s}\"" end end end end DB = Sequel.jdbc(:uri => 'jdbc:postgresql:postgres', :user => 'postgres', :password => 'postgres') Sequel::JDBC.load_driver('org.postgresql.Driver') DB[:user_data].all.each do |user_data| puts "#{user_data[:user_id]} #{user_data[:user_account].kconv(Kconv::SJIS, Kconv::UTF8)}" end
他にも罠がありそうで、JDBC接続でSequelを使うのは危険な感じがします。