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