それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

rubyのSequelをパパと使うサンプル(select/update/create/delete/unique/constrains)

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