Rails 5.2 加载顺序中断 db:create



我有一个 rails 应用程序,在 Rails 5.1 上创建 MySQL 数据库模式没有遇到任何问题,但在升级到 Rails 5.2 后无法创建。

似乎在 5.2 中,它尝试在创建数据库之前加载所有模型、观察器、狮身人面像索引等,而在 5.1 中,它以某种方式首先创建了数据库。

我认为问题不在于任何特定的 gem 或初始值设定项。我试图消除一些类似的observers只是为了看看它是否有任何区别,但无济于事。

使用 5.1 运行时,它显示如下内容:

$ rails db:create
...
Connected, but database does not exist: Unknown database '3scale_system_development'
Database '3scale_system_production' already exists
Created database '3scale_system_development'
Database '3scale_system_test' already exists
...

对于 5.2,它是

Connected, but database does not exist: Unknown database '3scale_system_development'
rake aborted!
ActiveRecord::NoDatabaseError: Unknown database '3scale_system_development'
/home/user/ws/repos/porta/app/indices/account_index.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/user.rb:21:in `<class:User>'
/home/user/ws/repos/porta/app/models/user.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:48:in `<class:EmailTemplate>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:42:in `block (2 levels) in <module:Provider>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:10:in `block in <module:Provider>'
/home/user/ws/repos/porta/app/models/account.rb:34:in `include'
/home/user/ws/repos/porta/app/models/account.rb:34:in `<class:Account>'
/home/user/ws/repos/porta/app/models/account.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:4:in `<class:AccountObserver>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/config/environment.rb:6:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Caused by:
Mysql2::Error: Unknown database '3scale_system_development'
/home/user/ws/repos/porta/app/indices/account_index.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/user.rb:21:in `<class:User>'
/home/user/ws/repos/porta/app/models/user.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:48:in `<class:EmailTemplate>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:42:in `block (2 levels) in <module:Provider>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:10:in `block in <module:Provider>'
/home/user/ws/repos/porta/app/models/account.rb:34:in `include'
/home/user/ws/repos/porta/app/models/account.rb:34:in `<class:Account>'
/home/user/ws/repos/porta/app/models/account.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:4:in `<class:AccountObserver>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/config/environment.rb:6:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:create => db:load_config => environment
(See full trace by running task with --trace)

知道会是什么吗?如果需要,您可以签出实际代码。

这是该项目的 5.1 版本: https://github.com/3scale/porta/commit/33cc4d5bcb5910295bfa28d84416ff05e1a606f3(现master分公司)

这是 5.2 升级版本: https://github.com/3scale/porta/commit/d75feac5cde9e085d5fdb2baa42c1fed674fceb8(现rails分公司)

我发现了导致问题的差异。在 5.1.7 中:

task :load_config do
ActiveRecord::Base.configurations       = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
end

在 5.2.7 中:

task load_config: :environment do
ActiveRecord::Base.configurations       = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
end

db:create任务取决于db:load_config任务。在 5.2 中,db:load_config任务取决于environment,它加载应用程序的所有观察器、狮身人面像索引等,这会触发在数据库尚不存在时无法建立的数据库连接。

我不知道我是否可以为我的应用程序合理轻松地解决此问题,但它至少回答了两者之间有什么区别的问题。

这是随 https://github.com/rails/rails/pull/31135 引入

的并且相对容易修复。你可以把你的Rakefile

Rake::Task['db:load_config'].clear_prerequisites

最新更新