DB にアクセスするなら Sequel が便利
データベースにアクセスしてデータを扱うには Sequel が便利。ActiveRecordもいいんだけどアレはめんどくさい。
SQLに極めて近い構造で余計なことはなにもなく便利でいい。
gem install sequel
DBに接続
DB = Sequel.connect('sqlite://./sample.db')
DB = Sequel.connect('mysql2://takuya:**pass**@192.168.100.1/takuya_db',:loggers => [Logger.new($stdout)])
create table をサンプル
DB.create_table!(:table) do
primary_key :id
String :user_name , :unique=>true
Char :role, default: 'u'
check(:role=>%w[a o u])
unique [:user_id, :group_id, :role]
end
select
シンボルで、ハッシュキーでアクセスする。面倒なときはクラスを定義する(後述)
res = db[:tablename]
res.all.each{|e|
puts res[:id]
puts res[:name]
}
insert のサンプル
obj = { name: "takuya"}
table = DB[:tablename]
table.insert(obj)
select のサンプル
table = DB[:tablename]
table = table.where( 'id > 1000' );
table.each{|r|
puts r[:id]
}
Where 句を使う
res = db[:tablename].where('id > 100')
res = db[:tablename].where('id > 100').where(' id < 1000 ')
SQL を確認する。
res = db[:tablename].where('id > 100').where(' id < 1000 ')
res.sql
delete のサンプル
table = DB[:tablename]
table = table.where( 'id = 1000' ).imit(1);
table.delete
update のサンプル
table = DB[:tablename]
table = table.where( 'id = 1000' ).imit(1);
obj = { name: "takuya"}
table.update(obj)
unique キーのエラーを検出
obj = { name: str1 , path: str2 }
begin
table = DB[:user_file_info]
table.insert(obj)
rescue Sequel::UniqueConstraintViolation => e
puts e.backtrace
raise e
end
prepare のサンプル
prepare = DB[:users].where('name like :n').prepare(:select,:select_by_name)
prepare.call(:n=>"%#{e}%")
create table のさらなる詳細。
DB.create_table!
DB.create_table?
DB.create_table
create table でのforeign key の指定
DB.create_table(:table) do
primary_key :id
foreign_key :user_id, :user
end
次のようにカスケードを指定する場合もあり。
foreign_key :user_id, :user, :on_update=>true
foreign_key :user_id, :user, :on_update=>true , :on_delte=>true
foreign_key :user_id, :user, :on_update=>true , :on_delte=>true,:deferrable=>true
外部キーのカラム名を別名にする時
DB.create_table(:table) do
primary_key :id
Integer :user_id
String :user_name
foreign_key [:user_id, :user_name], :user
end
各種制約をつける
DB.create_table(:table) do
primary_key :id
Integer :user_id
Integer :group_id
String : role
unique [:user_id, :group_id, :role]
デフォルト制約
role を [‘r’,‘o’,‘u’,] に制限する場合。
check(:role=>%w[a o u])
オブジェクトを使う。
クラス名を指定して扱える。テーブル名をハッシュで指定する。
class ImageCache < Sequel::Model(:image_cache)
end
r = ImageCache.all.first
r.url
テーブル名を省略するとクラス名の複数名になる。
class User < Sequel::Model(:users); end
class User < Sequel::Model; end
ActiveRecordじゃないとだめな人には此の方が便利かもしれない。
irb/pry を使ってるとき
irb でいっかいテーブルのクラス定義をしてしまうと、再定義がめんどくさいので。一旦消す方がいい。
pry を再起動せずに、クラスを消すには remove_const するのが楽
class UserInfoTable < Sequel::Model(:user_info_table); end
Object.class_eval { remove_const :UserInfoTable }
BLOB を突っ込む
バイナリを突っ込もうとしたらエラーになったことがあるので明示的にblob を指定する必要があった ( sqlite のとき )
obj = { image_url: image_url, image_data:Sequel.blob(bin) }
table = DB[:image_cache]
table.insert(obj)
sql を書くのをサボるのに便利。
ちょっとしたデータ処理でSQLでデータを格納したり、処理したりするのに便利。
ActiveRecordのようなモデルベースだと「アプリ」を使うには便利なんだけど、テーブルデータを触ったり増やしたりするにはとても不便なので、SequelはちょっとめんどくさいSQLをサボるのに便利だと思う。
参考資料
http://stackoverflow.com/questions/25657286/ruby-sequel-error-table-already-exists
http://stackoverflow.com/questions/10196624/how-to-check-constraints-in-sequel
http://takuya-1st.hatenablog.jp/entry/2015/12/28/204019
https://github.com/jeremyevans/sequel/blob/master/doc/schema_modification.rdoc