- 更新日: 2014年6月2日
- Rails
db/seeds.rb(rake db:seed)でSQLからDBに初期データ追加
Rails では db/seeds.rb を作成して rake db:seed コマンドでDBに初期データを追加できますが、そのデータ追加を SQL ステートメントから行う方法。以下のページが大変参考になりました。
Seed your Rails App by Importing from SQL | panupan.com
— 環境 —
Rails 4.0.1
db/seeds.rb の作成
上記ページのコードを参考にして変更した以下のコードを書いた。
db/seeds.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
unless Rails.env.production? connection = ActiveRecord::Base.connection tables = %w[table1 table2 table3] tables.each do |table| connection.execute("TRUNCATE #{table}") unless table == "schema_migrations" end # - IMPORTANT: SEED DATA ONLY # - DO NOT EXPORT TABLE STRUCTURES # - DO NOT EXPORT DATA FROM `schema_migrations` Dir.glob("db/sql_backup/*.sql").each do |sql_file| sql = File.read(sql_file) statements = sql.split(/;$/) statements.pop # the last empty statement ActiveRecord::Base.transaction do statements.each do |statement| connection.execute(statement) end end end end |
connection.tables は使わずに、tables 配列に手動で初期データを追加するテーブルを指定しました。また、Dir.glob で db/sql_backup/ 以下の、DB初期データ用の sql ファイルを全て読み込むようにしました。
DB に初期データ追加。
1 2 3 |
$ bundle exec rake db:seed |
必要な初期データを db/sql_backup/*.sql と sql ファイルで保存すればOK。これでいつでも、rake db:seed で DB に初期データを投入できる。
外部キー制約のあるテーブルを truncate しようとするとエラー
最初、参考ページのコード通りに connection.tables を使って schema_migrations 以外の全てのテーブルに対して TRUNCATE しようとしたらエラーが発生しました。
1 2 3 |
connection.tables.each do |table| connection.execute("TRUNCATE #{table}") unless table == "schema_migrations" end |
これだと以下のように、外部キー制約のあるテーブルの truncate ができない。
1 2 3 4 5 |
$ bundle exec rake db:seed rake aborted! ActiveRecord::StatementInvalid: Mysql2::Error: Cannot truncate a table referenced in a foreign key constraint |
以下のように一旦外部キー制約をオフにして TRUNCATE して、テーブルを TRUNCATE した後、再び外部キー制約をオンにするという方法が使えるらしい。
1 2 3 4 5 6 |
mysql> SET FOREIGN_KEY_CHECKS=0; mysql> TRUNCATE table1; mysql> TRUNCATE table2; mysql> SET FOREIGN_KEY_CHECKS=1; |
db/seeds.rb に書くなら以下のような感じかな。
1 2 3 4 5 |
connection.execute("SET FOREIGN_KEY_CHECKS=0;") connection.tables.each do |table| connection.execute("TRUNCATE #{table}") unless table == "schema_migrations" end connection.execute("SET FOREIGN_KEY_CHECKS=1;") |
しかし、私はこのやり方は若干怖い気がしたので、上記コードに書いたとおり初期データを追加するDBテーブル名を tables という配列で指定しました。外部キー制約のないテーブルに対する初期データ追加なら、これでOK。
- – 参考リンク –
- ruby on rails – Execute sql script inside seed.rb in rails3 – Stack Overflow
- MySQL で特定のテーブルのみをバックアップ | EasyRamble
- mysql – truncate foreign key constrained table – Stack Overflow
- mysqlの外部キー制約でtuncate table エラー ERROR 1701 (42000|IT忘備録・メモ書きと日記
- Rails の関連記事
- RailsでMySQLパーティショニングのマイグレーション
- Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
- RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
- RailsでAMPに対応するgemをリリースしました
- Railsでrequest.urlとrequest.original_urlの違い
- Railsでwheneverによるcronバッチ処理
- Google AnalyticsのRails Turbolinks対応
- Railsアプリにソーシャル・シェアボタンを簡単設置
- Rails監視ツール用にErrbitをHerokuで運用
- Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
Leave Your Message!