rake db tasks running twice
Asked Answered
E

2

10

I was seeding a development postgres database with a few thousand records from Faker when I caught a problem with the seed file. I aborted the seed operation and rolled back the inserts and fixed the seeds.rb file.

When I went to run it again, every rake db:* task runs twice. I can run rake routes just fine but if I run rake db:drop I get something like this:

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

If I try to run migrate the whole thing blows up when it tries to apply indexes, since it's already created those columns.

I've only got the one default Rakefile, and no custom rake files in lib or anywhere else.

The environment is rails 5.0.0.1 and ruby 2.2.2 if that makes any difference. I'm so lost over this right now.

Here is my 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

I've seen other threads suggesting it could be a problem with a gem, but I hadn't added a new gem in a few days when this problem started. Here's the gemfile anyway.

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]

Edit: I also tried a custom task in the db namespace and it works fine. Only runs once. From what I can tell, db:drop, db:create, db:reset, db:migrate are the only tasks running twice. Here's a trace on db:drop and another on 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
Ekg answered 7/10, 2016 at 5:23 Comment(2)
#35876161 does this help ?Micromho
I had actually been through that one, but I tried running their custom task from the Rakefile and it works perfectly. Just a single run, so it can't be the same cause as theirs. $ rake foo:bar RUNNING STILL RUNNING $ rake db:bar RUNNING STILL RUNNINGEkg
E
7

I found the culprit. Somewhere in the last few git commits, my database.yml was somehow duplicated.

Every time I tried to run any rake command that referenced the environment, it would run twice. Such a strange issue. Glad I was able to solve it.

Ekg answered 11/10, 2016 at 22:40 Comment(3)
I had a similar situation. I couldn't figure out WHY my structure load was failing with duplicate entries. Turns out that rails db:structure:load (and, I assume, all other db: tasks) will iterate through each database listed in database.yml, not just the development one. My DB was duplicated in test. I guess I can't do that :)Marlette
@DavidDombrowsky holy crap, this is exactly what my problem was. That seems like a blatant bug to me! Thanks, I was really confused by this.Indoctrinate
Same problem from me as I was pulling database names from the ENV like database: <%= ENV["MYSQL_DATABASE"] %> so all my environments had the same database and it was trying to run all environments, even when specifying the RAILS_ENV RAILS_ENV=development rake db:drop.Backswept
O
3

I wanted to elaborate on the accepted answer.

When you run db:schema:load, the Rake task definition inside Rails ultimately calls ActiveRecord::Tasks::DatabaseTasks.load_schema_current(). That happens here.

Inside that task it calls an internal method each_current_config.

That method loops through each environment (production, development, etc...) and yields the database configs for that environment to the block

As you can see, if the environment is development, it automatically adds test as an environment as well. This is for convenience, so that it also sets up the test db locally. If your development and test DB use the same DB name, it will try to create / load the same DB twice (and may run into an error on the second one).

You have a few options to avoid this:

  1. You can set SKIP_TEST_DATABASE=1, which will skip creating test
  2. You can specify a DATABASE_URL (instead of individual DB components), which will skip creating test
  3. You can give each environment a unique DB name which should avoid the conflict and allow you to create development and 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
Offering answered 10/8, 2022 at 20:47 Comment(1)
This information should really be with the accepted answer. Thank you.Columba

© 2022 - 2024 — McMap. All rights reserved.