在 Ruby on Rails 中使用固定装置播种数据是否危险
-
13-09-2019 - |
题
我的固定装置包含需要驻留在我的数据库中的初始数据(国家、地区、运营商等)。我有一个任务 rake db:seed 它将为数据库播种。
namespace :db do
desc "Load seed fixtures (from db/fixtures) into the current environment's database."
task :seed => :environment do
require 'active_record/fixtures'
Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
end
end
end
我有点担心,因为这个任务会清除我的数据库并加载初始数据。事实上,这甚至可以在生产中多次执行,这让我感到害怕。这是正常现象吗?我需要小心吗?或者人们通常会以某种方式保护这样的任务吗?
解决方案
用灯具播数据是一个极其坏主意。
照明灯不验证,因为大多数Rails开发人员不使用数据库的约束,这意味着你可以很容易地插入到你的生产数据库无效或不完整的数据。
照明灯也默认,这不一定是一个问题,但是烦人一起工作设定主怪密钥ID。
有很多关于这个解决方案。我个人最喜欢的是运行一个简单的使用ActiveRecord的插入记录的Ruby脚本rake任务。这是Rails 3的将db:seed
做,但你可以很容易地写自己。
我与I添加到的ActiveRecord ::基地称为create_or_update
的方法补充这一点。使用这个我可以多次运行脚本种子,更新旧的记录,而不是抛出异常。
我写这些技术而回叫加载种子数据的制品一>
其他提示
对于你的问题的第一部分,是的,我只希望把一些预防措施,在生产运行的任务是这样的。我把这样的保护我的引导/播种任务:
task :exit_or_continue_in_production? do
if Rails.env.production?
puts "!!!WARNING!!! This task will DESTROY " +
"your production database and RESET all " +
"application settings"
puts "Continue? y/n"
continue = STDIN.gets.chomp
unless continue == 'y'
puts "Exiting..."
exit!
end
end
end
我已经创建此要旨获取一些上下文。
有关问题的第二部分 - 通常你真的想两件事情:一)很容易播种的数据库和开发设置应用程序,和b)自举的生产服务器上的应用(如:插管理员用户,创建文件夹应用程序依赖等)。
我会用灯具播种发展 - 从团队中每个人那么看到相同的数据,应用程序和什么是在应用程序是什么在测试中保持一致。 (一般我包裹rake app:bootstrap
,rake app:seed
rake gems:install
等成rake app:install
所以每个人都可以通过只克隆回购和运行该一个任务上的应用程序工作。)
我但是从来没有用于播种/引导夹具生产服务器上。 Rails的db/seed.rb
是这个任务真的很好,但你当然可以把同样的逻辑在自己的rake app:seed
的任务,喜欢别人指出。
的Rails 3将解决这一您使用seed.rb文件。
http://github.com/brynary/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb
我们已经建立了一系列用于播种数据的最佳实践。我们严重依赖播种,并且我们有一些独特的要求,因为我们需要播种多租户系统。以下是我们使用过的一些最佳实践:
- Fixtures 不是最好的解决方案,但您仍然应该将种子数据存储在 Ruby 以外的地方。用于存储种子数据的 Ruby 代码往往会重复,将数据存储在可解析文件中意味着您可以编写通用代码来以一致的方式处理种子。
- 如果您可能要更新种子,请使用名为类似的标记列
code
将您的种子文件与实际数据相匹配。切勿依赖环境之间的 id 保持一致。 - 考虑一下您希望如何处理更新现有种子数据。用户是否有可能修改这些数据?如果是这样,您是否应该维护用户的信息而不是用种子数据覆盖它?
如果您对我们做种的某些方法感兴趣,我们已将它们打包到一个名为 gem 中 种子管理软件.
如何只删除任务关闭生产服务器,一旦你已经播种数据库?
我只是有一个有趣的想法......
如果您创建\ DB \种子\并添加迁移风格文件的内容:
文件:200907301234_add_us_states.rb
class AddUsStates < ActiveRecord::Seeds
def up
add_to(:states, [
{:name => 'Wisconsin', :abbreviation => 'WI', :flower => 'someflower'},
{:name => 'Louisiana', :abbreviation => 'LA', :flower => 'cypress tree'}
]
end
end
def down
remove_from(:states).based_on(:name).with_values('Wisconsin', 'Louisiana', ...)
end
end
交替:
def up
State.create!( :name => ... )
end
这将允许你在将允许他们更和平地共存的顺序运行的迁移和种子。
想法?