Рейк дб задачи выполняются дважды

Я заполнял базу данных postgres для разработки несколькими тысячами записей из Faker, когда обнаружил проблему с файлом seed. Я прервал операцию seed, откатил вставки и исправил файл seed.rb.

Когда я пошел, чтобы запустить его снова, каждый rake db:* задание выполняется дважды. я могу бежать rake routes очень хорошо, но если я бегу rake db:drop Я получаю что-то вроде этого:

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

Если я попытаюсь выполнить миграцию, все будет взорвано, когда он попытается применить индексы, поскольку он уже создал эти столбцы.

У меня есть только один Rakefile по умолчанию, и никаких пользовательских rake-файлов в lib или где-либо еще.

Среда это rails 5.0.0.1 и ruby ​​2.2.2, если это что-то меняет. Я так потерян из-за этого прямо сейчас.

Вот мой рейкфайл

# 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

Я видел другие темы, в которых говорилось, что это может быть проблемой с драгоценным камнем, но я не добавил новый драгоценный камень в течение нескольких дней, когда эта проблема началась. В любом случае, это гемфайл.

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: drop, db: create, db: reset, db: migrate - единственные задачи, выполняющиеся дважды. Вот след на db:drop и еще один на db: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

2 ответа

Решение

Я нашел виновника. Где-то в последние несколько коммитов git мой database.yml был как-то продублирован.

Каждый раз, когда я пытался запустить любую команду rake, которая ссылалась на окружение, она запускалась дважды. Такая странная проблема. Рад, что мне удалось это решить.

Я хотел уточнить принятый ответ.

Когда вы бежитеdb:schema:load, определение задачи Rake внутри Rails в конечном итоге вызываетActiveRecord::Tasks::DatabaseTasks.load_schema_current(). Это происходит здесь .

Внутри этой задачи он вызывает внутренний методeach_current_config.

Этот метод перебирает каждую среду (production, , и т.д...) иyieldsконфигурации базы данных для этой среды вblock

Как видите, если среда имеет значение , она также автоматически добавляется в качестве среды. Это сделано для удобства, чтобы он также устанавливал базу данных локально. Если ваша и БД используют одно и то же имя БД, она попытается создать/загрузить одну и ту же БД дважды (и может столкнуться с ошибкой на втором).

У вас есть несколько вариантов избежать этого:

  1. Вы можете установитьSKIP_TEST_DATABASE=1, который пропустит создание
  2. Вы можете указатьDATABASE_URL(вместо отдельных компонентов БД), что позволит пропустить создание
  3. Вы можете дать каждой среде уникальное имя БД, которое должно избежать конфликта и позволить вам создаватьdevelopmentиtest
      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
Другие вопросы по тегам