I have a rails app that I'm moving to another server and I figure I should use db:schema:load to create the mysql database because it's recommended. My problem is that I'm using capistrano to deploy and it seems to be defaulting to rake db:migrate instead. Is there a way to change this or is capistrano using db:migrate for a good reason?
Answer 1:
为什么要使用DB:架构:负载
我发现我自己的迁移,最终的数据做一些洗牌(假设我结合FIRST_NAME和姓氏列插入FULL_NAME列,例如)。 当我做任何的这个,我开始使用ActiveRecord通过数据库中的记录进行筛选,并且您的模型,最终做出某些列的假设。 我的“人”表,例如,后来鉴于人们排序“位置”栏。 此前迁移现在无法选择的数据,因为“位置”栏尚不存在。
如何更改Capistrano的默认行为
总之,我相信deploy:cold
应使用db:schema:load
,而不是db:migrate
。 我通过改变Capistrano的执行在一个寒冷的部署中间一步解决了这个问题。 对于Capistrano的v2.5.9,在库代码默认任务看起来是这样的。
namespace :deploy do
...
task :cold do
update
migrate # This step performs `rake db:migrate`.
start
end
...
end
我推翻了任务,我deploy.rb
如下。
namespace :deploy do
task :cold do # Overriding the default deploy:cold
update
load_schema # My own step, replacing migrations.
start
end
task :load_schema, :roles => :app do
run "cd #{current_path}; rake db:schema:load"
end
end
Answer 2:
在安德烈家安粘性,亚当尖塔和Kamiel Wanrooij的肩膀上攀登,我已经建立了以下任务覆盖部署:冷。
task :cold do
transaction do
update
setup_db #replacing migrate in original
start
end
end
task :setup_db, :roles => :app do
raise RuntimeError.new('db:setup aborted!') unless Capistrano::CLI.ui.ask("About to `rake db:setup`. Are you sure to wipe the entire database (anything other than 'yes' aborts):") == 'yes'
run "cd #{current_path}; bundle exec rake db:setup RAILS_ENV=#{rails_env}"
end
我在这里的改进是...
- 敷在
transaction do
,这样会Capistrano的中止后做一个适当的回滚。 - 做
db:setup
,而不是db:schema:load
,因此,如果数据库不存在,它将被载入架构之前创建的。
Answer 3:
这是一个从安德烈斯家安粘性很大的答案。 我只想补充几点看法。
首先,这里的安德烈的改进版deploy:load_schema
任务,其中包含一个警告,更重要的是采用bundle exec
和RAILS_ENV
,以确保环境设置正确:
namespace :deploy do
desc 'Load DB schema - CAUTION: rewrites database!'
task :load_schema, :roles => :app do
run "cd #{current_path}; bundle exec rake db:schema:load RAILS_ENV=#{rails_env}"
end
end
我已经提交了一个功能请求,有deploy:load_schema
在Capistrano的实现 。 在这种要求,我注意到, 在“ db:schema:load
与db:migrate
”的争论已经覆盖了Capistrano的讨论组中 ,并且有一些不愿意交换机deploy:cold
任务使用db:schema:load
超过db:migrate
,因为如果无意中运行,前者核武器整个数据库,而后者可能会抱怨和无害保释。 然而db:schema:load
是在技术上更好的方法,因此,如果数据意外丢失的风险可以得到缓解,这将是值得切换。
Answer 4:
在Capistrano的3 /轨道4,默认部署语法发生了变化。 你可以这样做,而不是:
desc 'Deploy app for first time'
task :cold do
invoke 'deploy:starting'
invoke 'deploy:started'
invoke 'deploy:updating'
invoke 'bundler:install'
invoke 'deploy:db_setup' # This replaces deploy:migrations
invoke 'deploy:compile_assets'
invoke 'deploy:normalize_assets'
invoke 'deploy:publishing'
invoke 'deploy:published'
invoke 'deploy:finishing'
invoke 'deploy:finished'
end
desc 'Setup database'
task :db_setup do
on roles(:db) do
within release_path do
with rails_env: (fetch(:rails_env) || fetch(:stage)) do
execute :rake, 'db:setup' # This creates the database tables AND seeds
end
end
end
end
如果你是谨慎调用标准的手动部署的任务:cold
任务(因为他们可能在即将到来的版本,或者改变您有一个自定义部署任务),你也可以简单地调用deploy:db_setup
在运行之前deploy
。
要执行db:schema:load
,而不是db:setup
,你可以简单地改变rake任务,就像这样:
desc 'Load DB Schema'
task :db_schema_load do
...
execute :rake, 'db:schema:load'
...
end