【问题标题】:Capistrano deploy:migrate and db:migrate run all migrations every timeCapistrano deploy:migrate 和 db:migrate 每次运行所有迁移
【发布时间】:2013-06-26 19:48:12
【问题描述】:

所以,我在使用 rails(ruby 1.9.3p392、rails 3.2、sqlite3 db),我正在尝试将无处不在的博客教程代码部署到“生产”服务器(apache、passenger、ubuntu)。我的 deploy.rb 看起来像这样:

require 'bundler/capistrano'
require 'rvm/capistrano'
load 'deploy/assets'
set :rvm_ruby_string,  ENV['GEM_HOME'].gsub(/.*\//,"")
set :rvm_type, :user
set :user, 'blah'
set :application, 'railsTest'
set :domain, 'www.blah.com'
set :applicationdir, "/home/sean/public/blah.com/public"
set :scm, 'git'
set :repository,  "ssh://blah@1.1.1.1/home/blah/public/bla.com/public/capDep.git"
#set :git_enable_submodules, 1 # if you have vendored rails
set :branch, 'master'
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false


# roles (servers)
role :web, domain
role :app, domain
role :db,  domain, :primary => true

# deploy config
set :deploy_to, applicationdir
set :deploy_via, :export
set :migrate_target, :latest
# additional settings
default_run_options[:pty] = true  # Forgo errors when deploying from windows
#ssh_options[:keys] = %w(/home/blah/.ssh/id_rsa)
ssh_options[:forward_agent] = true
# if you want to clean up old releases on each deploy uncomment this:

# If you are using Passenger mod_rails uncomment this:
namespace :deploy do
  task :start do ; end
  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
  end
end

#after "deploy:update_code", "deploy:migrate"

现在,我敢肯定,对于那些知道自己在用 capistrano 做什么的人来说,这看起来一定是一团糟,但我是个彻头彻尾的笨蛋。最后,尽管我的不足,部署似乎工作,因为当我运行以下

cap deploy:setup
cap deploy

我的应用程序已启动并正在运行,正因为我可以,我通过 rails 为我创建的 web ui 在数据库中的表中添加了几行。现在,我变得粗体并创建一个迁移,向表中添加一列。我将更改推送到 git。令我惊恐的是,当我跑步时

cap deploy

所有迁移都运行,这会重新创建表,从而破坏我的所有数据。我已经多次重复这个痛苦的过程。我的 schema_migrations 表如下所示:

20130620210004
20130620220229
20130628213331
20130628214946
20130628223002

我在这里缺少什么?

更新:我最近向@TheMahrvin 提出了关于在命令行运行 deploy:migrations 并将其从 deploy.rb 中删除的建议。它没有用......再一次,所有迁移都运行了。我的缪斯女神一定在我耳边耳语了些什么,因为我决定尝试在服务器本身上运行 db:migrate。在运行“rake”后看到这个输出我很惊讶:

  20130717230110 CreateHighScores
  20130717230342 CreateGames
  20130717231041 AddGameTypeToGame
  20130717233707 AddGamePublisherToGame
  20130717234124 AddGameRatingToGame
  20130731210558 AddGameMechanicToGame

只有最后的迁移应该是挂起的。所以,也许这根本不是 Capistrano 的问题(我已经更新了这个问题的标题以反映这一点)。那么,为什么之前的迁移仍被标记为待处理?我知道它们过去曾运行过,因为我在输出中看到了它们并在它们运行后验证了 db 架构。

更新 #2: 设置另一个迁移并 ssh'd 进入服务器并 cd'd 我的方式到“当前”目录,如果我完全理解 capistrano(很大的机会)是在哪里当前文件是。跑步

bundle exec rake db:migrate:status

找我:

 Status   Migration ID    Migration Name
--------------------------------------------------
  down    20130717230110  Create high scores
  down    20130717230342  Create games
  down    20130717231041  Add game type to game
  down    20130717233707  Add game publisher to game
  down    20130717234124  Add game rating to game
  down    20130731210558  Add game mechanic to game
  down    20130731212454  Add publish year to game
  down    20130731214515  Add game rank to game
  down    20130731214928  Add game abbr to game
  down    20130731215749  Add crazy field to game

我不禁感到我正在尝试做的事情有严重的错误。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 rake capistrano


    【解决方案1】:

    好的,想通了...尽管根据我最初问题中的红鲱鱼,stackosphere 中的其他人应该如何做同样的事情。

    问题是我的生产数据库设置为

    db/production.sqlite3
    

    因为它是主项目目录中的一个sqlite数据库,所以每次我运行它都会被砍掉

    cap deploy
    

    然后,我什么时候跑

    cap deploy:migrate
    

    它会找到一个空数据库并认为需要运行所有迁移。我通过将数据库路径更改为

    解决了这个问题
    /my_absolute_path/shared/db/production.sqlite3
    

    感谢@TheMahvin 和其他任何试图承担无望的任务来回答我措辞不佳的问题的人!

    H/T 到这个问题,这让我眼中的鳞片掉了下来:

    Capistrano Deploy Wipes Database?

    【讨论】:

      【解决方案2】:

      您是如何“向数据库中的表添加几行”的?
      我怀疑您的数据丢失是由于混合迁移和您自己的数据库更改造成的。 Rails 希望您通过迁移来完成所有数据库更改。
      Rails 社区中普遍存在关于迁移的一些争论,但现在(尤其是如果您是初学者)总是使用迁移来更改您的数据库。这样一来,您就有了一个完整的数据库蓝图,允许您从头开始在多台机器上进行部署,而无需摆弄您的数据库,并确保其他贡献者使用相同的数据库。

      我对这些内部结构了解不多,但据我了解,您的数据丢失导致了类似情况:

      在您手动更改后,Rails 无法将 db-layout 与任何迁移的结果匹配(分别通过迁移和架构中的时间戳),因此将 db 视为新数据库。要达到所有迁移定义的状态,需要执行所有迁移,包括创建表的迁移,从而丢弃其中的所有内容。

      希望对你有帮助,
      安迪

      【讨论】:

      • 感谢您的回复...我认为这个问题已被委托在外在的黑暗中永远消沉。我使用Web应用程序界面将行添加到数据库中的表中......也就是说,部署,转到站点并导航到控制器的“创建”视图,填写html表单并点击提交。然后,冲洗并再重复几次。
      • 无意冒犯,但这似乎没有任何意义。 Rails 不会通过将数据库模式与迁移结果进行比较来确定您的迁移级别。它创建一个名为schema_migrations 的表,并存储已在其中运行的每个迁移的时间戳。当您运行rake db:migrate 时,它会将schema_migrations 中的时间戳与db/migrate 中存在的迁移文件的时间戳进行比较。
      • 未拍摄。其实我什至认为你的评论符合我的部分描述。我只是对匹配的详细工作方式一无所知:迁移的结果可以通过时间戳来识别,实际的数据库布局也可以通过模式的时间戳来识别。但是,是的,丢弃部分并没有真正的意义。我只是在猜测。我应该删除答案吗?
      【解决方案3】:

      我没见过:

      after "deploy:update_code", "deploy:migrate"
      

      之前。尝试删除该行并运行:

       bundle exec cap deploy:migrations (deploys code and migrations)
      

       bundle exec cap deploy:migrate (runs the migrate rake task on the server)
      

      相反。 你的 deploy.rb 的其余部分对我来说似乎没问题,虽然我对 rvm/capistrano 集成或 windows 调整一无所知。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-03
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 2012-02-05
        • 2011-07-11
        相关资源
        最近更新 更多