【问题标题】:Why Does First Deploy with Capistrano Run db:migrate?为什么首先使用 Capistrano 部署运行 db:migrate?
【发布时间】:2014-03-06 10:48:59
【问题描述】:

我第一次使用 Capistrano 部署到生产环境,运行时出现错误

cap production deploy

错误是:

** Invoke deploy:migrate (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:migrate
DEBUG [048f89c6] Running /usr/bin/env if test ! -d /home/deployer_user/apps/ap_production/releases/20140209005208; then echo "Directory does not exist '/home/deployer_user/apps/ap_production/releases/20140209005208'" 1>&2; false; fi on eslope.net
DEBUG [048f89c6] Command: if test ! -d /home/deployer_user/apps/ap_production/releases/20140209005208; then echo "Directory does not exist '/home/deployer_user/apps/ap_production/releases/20140209005208'" 1>&2; false; fi
DEBUG [048f89c6] Finished in 0.160 seconds with exit status 0 (successful).
INFO [52f75214] Running ~/.rbenv/bin/rbenv exec bundle exec rake db:migrate on eserver.net
DEBUG [52f75214] Command: cd /home/deployer_user/apps/ap_production/releases/20140209005208 && ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.0 RAILS_ENV=production ~/.rbenv/bin/rbenv exec bundle exec rake db:migrate )
DEBUG [52f75214]    rake aborted!
DEBUG [52f75214]    An error has occurred, this and all later migrations canceled:
DEBUG [52f75214]    
DEBUG [52f75214]    PG::UndefinedTable: ERROR:  relation "client_infos" does not exist
DEBUG [52f75214]    : ALTER TABLE "client_infos" RENAME TO "clients

这个错误实际上是完全有道理的。引用的表不存在。我不明白为什么迁移正在运行?为什么不是在第一次运行时从模式中创建数据库。我是否无意中删除了说明已运行哪些迁移的文件?要么直接删除它,要么通过“.gitignoring”它?

我想我知道如何修复它(rake db:create 或类似的),但我不明白的是,如果在 Capistrano v3 中它知道这是第一次,为什么它不会直接使用模式而不是运行所有迁移?我是一个菜鸟,这似乎是合理的,但另一方面,运行迁移会达到相同的结果,所以......(但是那些在生产中不盲目使用迁移的人呢;不会他们被卡住了吗?)谢谢。

【问题讨论】:

  • 看起来不像是一套用于部署的 capistrano 配方,所以很难说是什么原因造成的。
  • 例如,为什么第一次运行不做这样的事情:RAILS_ENV=production rake db:create db:schema:load
  • 你试过cap deploy:cold 吗?
  • gmaliar - 很棒的建议,但 cap deploy:cold 在 Capistrano v3 中已被弃用,我应该提到我正在使用它。

标签: ruby-on-rails migration capistrano capistrano3


【解决方案1】:

最终我所做的就是按照 lmars 和 Nick 的建议。我直接在生产机器上运行了这样的东西:

RAILS_ENV=production bundle exec rake db:drop
RAILS_ENV=production bundle exec rake db:schema:create
RAILS_ENV=production bundle exec rake db:schema:load

这当然会破坏数据库中的数据,但在第一次部署时,这不是问题。

我认为有一个更简单的方法,但是...我不知道。

【讨论】:

    【解决方案2】:

    db:migrate 获取迁移文件并执行它们。 所以如果一个表不存在,它会告诉你。如果您的部署是第一次部署到该机器,或者配置的数据库尚未初始化,您应该这样做:

    1. 创建数据库

      rake db:create

    这将创建所有表

    2 运行迁移

     `rake db:migrate`
    

    显然,您需要进行迁移。

    强烈建议不要加载架构(除非您别无选择),因为在(回滚等)之后很难处理架构,但如果您别无选择,您可以执行 rake db:schema:load

    查看更多信息

    rake db:schema:load vs. migrations

    How to update production database schema safely in rails 3.1.3?

    【讨论】:

    • 谢谢尼克。绝对有用的信息,我想我可能会按照您的建议做,但在这种情况下,我的问题实际上是关于 Capistrano (v3.x) 为何正在做它正在做的事情。我希望能够弄清楚,这样如果我再次以这种方式部署,它就会起作用。(我对您的回复进行了升级。)
    • 我相信我无法运行 rake db:create 来成功部署,因为在部署之前我在远程服务器上没有任何项目文件,除了手动创建的 database.yml,所以只需 rake没有 rakefile 将无法运行。在第一次部署之前,我是否应该做任何事情来运行 rake?
    【解决方案3】:

    检查你的 database.yml 配置,生产部分,如果它是正确的。然后确保 Postgresql 服务器正在生产服务器上运行,并且应用程序(作为用户)具有访问权限。我假设“部署者”是用户,因此请检查此用户是否拥有所有必要的权限。

    【讨论】:

    • Nikos,感谢您的建议。我可以使用 psql -h(IP 地址)-U(正确的用户名)和 -d(数据库名称)从另一台机器进行连接。数据库用户与部署者不同,但我将 db 设置为 m5,并且 database.yml 部分(唯一的部分是 prod)看起来不错。
    【解决方案4】:

    从错误来看,您似乎正在尝试将client_infos 表重命名为clients,但client_infos 表不存在,但您是否没有创建client_infos 表的早期迁移?

    如果您没有创建client_infos 表的迁移,那么它是从哪里来的?你是手动创建的吗?对数据库的所有更改都应伴随迁移。

    如果您确实对client_infos 表进行了迁移,那么schema_migrations 数据库表(Rails 记录已运行迁移的地方)可能会以某种方式不同步。鉴于您是第一次部署,可能值得删除整个数据库并重新开始。

    我不明白为什么迁移正在运行?为什么不是在第一次运行时从架构创建数据库

    如果编写正确,迁移应该与加载架构具有相同的效果,它们只会增量执行。如果您愿意,当然可以手动加载架构,但 Capistrano 不会这样做,因为运行起来非常危险(您可能永远不想重新创建生产数据库)

    【讨论】:

    • Imars,感谢您查看此内容。你是对的,错误是关于桌子的(我想在我的问题中我注意到它抱怨的桌子不存在)。我的问题实际上是关于为什么在这种情况下迁移正在运行。我提高了你的答案,我不认为它回答了这个问题(尽管它确实给了我更多关于如何解决它的想法)。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多