运行两次Rake db任务



当我发现种子文件有问题时,我正在用Faker的几千条记录播种一个开发postgres数据库。我中止了种子操作,回滚了插入并修复了种子。rb文件。

当我再次运行它时,每个rake db:*任务运行两次。我可以运行rake routes但如果我运行rake db:drop,我会得到这样的结果:

$ rake db:drop
Dropped database 'vp_development'
Dropped database 'vp_development'

如果我尝试运行migrate,当它尝试应用索引时,整个事情就会崩溃,因为它已经创建了这些列。

我只有一个默认的rake文件,没有自定义的rake文件在库或其他任何地方。

如果有区别的话,环境是rails 5.0.0.1和ruby 2.2.2。我现在对这件事很迷茫。

这是我的Rakefile

# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative 'config/application'
Rails.application.load_tas

我已经看到其他线程暗示这可能是一个宝石的问题,但我没有添加一个新的宝石在几天当这个问题开始。这就是gemfile。

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
gem 'puma', '~> 3.0'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'jquery-rails'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'devise'
gem 'bootstrap-sass', '3.3.6'
gem 'pg'
gem 'friendly_id'
gem 'will_paginate'
gem 'faker'
group :development, :test do
  #gem 'sqlite3'
  gem 'byebug', platform: :mri
end
group :development do
  gem 'web-console'
  gem 'listen', '~> 3.0.5'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end
group :production do
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

编辑:我还尝试了一个自定义任务在db命名空间,它工作得很好。只运行一次。据我所知,db:drop, db:create, db:reset, db:migrate是唯一运行两次的任务。下面是db:dropdb:create的跟踪。

 $ rake db:drop --trace
** Invoke db:drop (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Invoke db:check_protected_environments (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config 
** Execute db:check_protected_environments
** Execute db:drop
** Invoke db:drop:_unsafe (first_time)
** Invoke db:load_config 
** Execute db:drop:_unsafe
Dropped database 'vp_development'
Dropped database 'vp_development'
rake db:create --trace
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:create
Created database 'vp_development'
Database 'vp_development' already exists

我找到了罪魁祸首。在最近几次git提交的某个地方,我的数据库。Yml被复制了

每次我试图运行任何引用环境的rake命令时,它都会运行两次。真是个奇怪的问题。很高兴我能解决这个问题

我想详细说明这个公认的答案。

运行db:schema:load时,Rails中的Rake任务定义最终调用ActiveRecord::Tasks::DatabaseTasks.load_schema_current()

在该任务内部,它调用一个内部方法each_current_config

该方法循环遍历每个环境(production, development等)和yields,该环境的数据库配置到block

如您所见,如果环境是development,它会自动地也将test添加为环境。这是为了方便,所以它也在本地设置test db。如果您的developmenttest数据库使用相同的数据库名称,它将尝试创建/加载相同的数据库两次(并且可能在第二次上遇到错误)。

你有几个选项可以避免这种情况:

  1. 您可以设置SKIP_TEST_DATABASE=1,它将跳过创建test
  2. 您可以指定DATABASE_URL(而不是单独的DB组件),它将跳过创建test
  3. 您可以给每个环境一个唯一的DB名称,这应该避免冲突,并允许您创建developmenttest
default: &default
  adapter: postgresql
  encoding: unicode
  host: <%= ENV.fetch('POSTGRES_HOST', 'localhost') %>
  port: <%= ENV.fetch('POSTGRES_PORT', 5432) %>
  username: <%= ENV.fetch('DATABASE_USERNAME', 'postgres') %>
  password: <%= ENV.fetch('DATABASE_PASSWORD', '') %>
  pool: <%= ENV.fetch('DATABASE_CONNECTION_POOL', 5) %>
  timeout: <%= ENV.fetch('DATABASE_TIMEOUT', 5000) %>
test: &test
  <<: *default
  min_messages: warning
  database: <%= ENV.fetch('DATABASE_NAME', 'foo_test') %>
development:
  <<: *default
  database: <%= ENV.fetch('DATABASE_NAME', 'foo_development') %>
staging:
  <<: *default
production:
  <<: *default

最新更新