Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rails db:drop:all db:create:all db:migrate isn't creating tables after adding InternalMetadata/EnvironmentMismatchError #23279

Closed
ojab opened this issue Jan 27, 2016 · 40 comments
Assignees
Milestone

Comments

@ojab
Copy link
Contributor

ojab commented Jan 27, 2016

Right now rails db:drop:all db:create:all db:migrate leaves DB without any tables, before adding internal metadata this command resulted in migrated DB.
Unfortunately I can't bisect the issue because in many commits dropping/creating/migration in a single run is broken, but AFAICS the issue emerged after adding InternalMetadata/EnvironmentMismatchError.

The first bad commit could be any of:
d70c68d
f6628ad
c1a1595
de2cb20
302e923
a76c423
350ae6c
ab40d71
7b065f6
9219976
30391e9
900bfd9
34ac8a1
We cannot bisect more!

cc @schneems

@prathamesh-sonpatki
Copy link
Member

May be we can run bin/rails db:environment:set before rails db:migration is run?

r? @schneems

@prathamesh-sonpatki
Copy link
Member

Confirmed this issue on master.

@schneems
Copy link
Member

Are you getting any errors or output? Can you run with --trace?

@prathamesh-sonpatki
Copy link
Member

Getting this output

rails aborted!
ActiveRecord::NoEnvironmentInSchemaError: 

Environment data not found in the schema. To resolve this issue, run: 

    bin/rails db:environment:set RAILS_ENV=development

bin/rails:4:in `require'
bin/rails:4:in `<main>'

@schneems
Copy link
Member

This is what I get

2.3.0  /tmp/blerg
$ rails db:drop:all db:create:all db:migrate --trace
** Invoke db:drop:all (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:all
** Invoke db:create:all (first_time)
** Invoke db:load_config
** Execute db:create:all
** Invoke db:migrate (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:migrate
== 20160127151202 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0016s
== 20160127151202 CreateUsers: migrated (0.0016s) =============================

** Invoke db:_dump (first_time)
** Execute db:_dump
** Invoke db:schema:dump (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:dump

Though it still doesn't have tables

$ rails dbconsole
.tabglSQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> .tables
sqlite>

@schneems
Copy link
Member

Weird that running only the db:migrate works

$ rake db:migrate
== 20160127151202 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0012s
== 20160127151202 CreateUsers: migrated (0.0013s) =============================

2.3.0  /tmp/blerg
$ rails dbconsole
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> .tables
active_record_internal_metadatas  users
schema_migrations

@ojab
Copy link
Contributor Author

ojab commented Jan 27, 2016

Getting the same as @schneems here, but saw bin/rails db:environment:set RAILS_ENV=development error during bisecting.

@schneems
Copy link
Member

You'll get that error if you're trying to run that command on a non-empty database that was upgraded from Rails 4.2. To resolve it follow directions, run that command. That error is expected, there's no way around it, running it is part of the upgrade process.

I'm running off of a rails new app with Rails 5 pointing at master in the Gemfile.

This command also works:

$ rails db:drop db:create db:migrate --trace

I'm thinking there's some strange interaction with the :all invocations.

@prathamesh-sonpatki
Copy link
Member

I am also getting same output now, in my case the database did not had anything in active_record_internal_metadatas so the error related to missing data was thrown for the first time.

But now I am getting same issue from #23279 (comment) 😄

@schneems
Copy link
Member

It works if you don't do all on db:create

$ env VERBOSE=true rails db:drop:all db:create db:migrate --trace

@schneems
Copy link
Member

BTW I figured out a one liner to test (if you're using a SQLite3 database

$ env VERBOSE=true rails db:drop:all db:create:all db:migrate --trace && echo ".tables" | rails dbconsole

@schneems
Copy link
Member

I figured out what is going on. I added some logging to see what database we are connected to

$ env VERBOSE=true rails db:drop:all db:create:all db:migrate --trace && echo ".tables" | rails dbconsole
** Invoke db:drop:all (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
== Connecting to database: nil
** Invoke db:load_config
** Execute db:check_protected_environments
** Execute db:drop:all
** Invoke db:create:all (first_time)
** Invoke db:load_config
** Execute db:create:all
== Connecting to database: {"adapter"=>"sqlite3", "pool"=>5, "timeout"=>5000, "database"=>"db/development.sqlite3"}
== Connecting to database: {"adapter"=>"sqlite3", "pool"=>5, "timeout"=>5000, "database"=>"db/test.sqlite3"}
== Connecting to database: {"adapter"=>"sqlite3", "pool"=>5, "timeout"=>5000, "database"=>"db/production.sqlite3"}
** Invoke db:migrate (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:migrate
========
"development"
== 20160127151202 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0012s
"development"
== 20160127151202 CreateUsers: migrated (0.0013s) =============================

** Invoke db:_dump (first_time)
** Execute db:_dump
** Invoke db:schema:dump (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:dump

Notice that the last database to connect is production, so let's check production

$ echo ".tables" | RAILS_ENV=production rails dbconsole
active_record_internal_metadatas  users
schema_migrations

Bingo. Now there's the question of what changed to cause this behavior? The reason that db:create:all doesn't work but db:create does is that it creates and establishes the development connection

ActiveRecord::Base.establish_connection(environment.to_sym)
so then db:migrate will use that connection.

We can fix this by explicitly connecting to the "current" database at the end of create_all method in the database tasks, but since we didn't need it before i'm hesitant to use it now.

Here's my guess: i'm thinking that previously AR wasn't "connected" to any database. The "create" action used in the rake task doesn't use ActiveRecord::Base.establish_connection instead it uses

def create(*arguments)
configuration = arguments.first
class_for_adapter(configuration['adapter']).new(*arguments).create
rescue DatabaseAlreadyExists
$stderr.puts "#{configuration['database']} already exists"
rescue Exception => error
$stderr.puts error
$stderr.puts "Couldn't create database for #{configuration.inspect}"
raise
end
. So when db:migrate gets called it sees that it isn't connected to a DB, tries to connect, succeeds and then migrates the database.

My patch changed the behavior because now we have to ActiveRecord::Base.establish_connection to check for protected environments. Now when rake gets around to running db:migrate it sees a connection is alive so it uses that instead of creating a new one, it just so happens the last one it established to was "production" so that gets used instead of the one we currently want.

If i'm right about the cause, then it was basically working by accident before.

Any ideas @sgrif ?

@sgrif sgrif assigned schneems and sgrif and unassigned schneems Feb 2, 2016
@schneems
Copy link
Member

schneems commented Feb 2, 2016

I've been thinking we should maybe explicitly do an establish_connection before the migration task.

@bquorning
Copy link
Contributor

Any progress on this issue? It’s blocking us from making a few (private) gems ready for Rails 5. Update: it turned out not to be a blocker for us anyway.

@schneems
Copy link
Member

ping @sgrif you assigned this to yourself, do you have an idea on a fix?

@Schwad
Copy link
Contributor

Schwad commented Sep 1, 2016

Our company is running into this same issue on ourgitlab-ci, is the current fix part of Rails core for 5.0.0.1?

@ojab
Copy link
Contributor Author

ojab commented Sep 1, 2016

This issue is fixed in 5.0.0 and doesn't affect any release version of rails.

@estiens
Copy link

estiens commented Oct 5, 2016

I get this behavior (or similar) with Rails 5.0.0.1

$ bin/rails db:environment:set RAILS_ENV=development
(works fine)
$ bin/rails db:drop
rails aborted!
ActiveRecord::NoEnvironmentInSchemaError:

Environment data not found in the schema. To resolve this issue, run:

    bin/rails db:environment:set RAILS_ENV=development

@alex-j-s
Copy link

alex-j-s commented Oct 5, 2016

@estiens Same here popped up today

@itsterry
Copy link

itsterry commented Oct 6, 2016

I had this problem on our CI setup, and fixed it with

rake db:schema:dump

@schneems
Copy link
Member

schneems commented Oct 6, 2016

Anyone have an example app with steps to repro the problem? I'm not exactly sure the underlying failure mode. That first command should populate the internal metadata table, and that should be all we need. I'm wondering if it's trying to drop a different database somehow.

@vgonda
Copy link

vgonda commented Oct 18, 2016

I was able to reproduce the error:

  • Created a new migration
  • rake db:migrate
  • bin/rails db:environment:set RAILS_ENV=test
  • 👍
  • rake db:rollback
  • Changed migration
  • rake db:migrate
  • bin/rails db:environment:set RAILS_ENV=test
  • 😞 Unable to update the testing environment with the migration change due to ActiveRecord::NoEnvironmentInSchemaError

This is with 5.0.0

@schneems
Copy link
Member

schneems commented Oct 18, 2016

Please provide an example app

@Schwad
Copy link
Contributor

Schwad commented Nov 2, 2016

@vgonda : do you have an example app of this?

@vgonda
Copy link

vgonda commented Nov 2, 2016

I don't 😞 I was able to reproduce it in a private repo, but I haven't been able to reproduce since.

@Schwad
Copy link
Contributor

Schwad commented Nov 3, 2016

Dang, well maybe if we summon the @group we could get someone who has an
example app.... OR if someone is currently facing this issue and they come
here via googling around they should really share an example app! :D

On 2 November 2016 at 17:56, Victoria Gonda notifications@github.com
wrote:

I don't 😞 I was able to reproduce it in a private repo, but I haven't
been able to reproduce since.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#23279 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AHgCxk78wUq6j9vuK4mYz01TI5eEy45mks5q6M7igaJpZM4HNcsZ
.

@mvz
Copy link

mvz commented Nov 27, 2016

@Schwad I came here by googling. My problem may not be the same but seems related. And I have a super-simple reproduction:

git clone git@github.com:publify/publify_amazon_sidebar.git
cd publify_amazon_sidebar
bundle exec rake

I get the following output:

/home/matijs/.rbenv/versions/2.3.1/bin/ruby -I/home/matijs/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib:/home/matijs/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-support-3.5.0/lib /home/matijs/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
rails aborted!
ActiveRecord::EnvironmentMismatchError: You are attempting to modify a database that was last run in `development` environment.
You are running in `test` environment. If you are sure you want to continue, first set the environment using:

	bin/rails db:environment:set RAILS_ENV=test

bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:test:load => db:test:purge => db:check_protected_environments
(See full trace by running task with --trace)
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}

[snip rest of successful RSpec run output]

@rquant
Copy link

rquant commented Nov 28, 2016

I strangely got this error when checking out a pre Rails 5 commit in our repo, loading schema from that commit and then going back to HEAD commit with Rails 5.

Ryans-MacBook-Pro:matic-home ryanquant$ bin/rails db:reset
I, [2016-11-28T08:55:41.209693 #15269]  INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
rails aborted!
ActiveRecord::NoEnvironmentInSchemaError: 

Environment data not found in the schema. To resolve this issue, run: 

        bin/rails db:environment:set RAILS_ENV=development

Any db rake/rails command I tried to run would cause the error to be thrown (even after running the environment setup command recommended in the error).

Strangely, when the one exception is when I ran bin/rails db:migrate. The normal behavior resumed and the errors were no more.

@Schwad
Copy link
Contributor

Schwad commented Nov 29, 2016

Interesting. What do you make of this @schneems ?

@ojab
Copy link
Contributor Author

ojab commented Nov 29, 2016

app:update task (that should be run after upgrade, according to the guide) deals with it.
AFAIU it is intended behavior.

@tfluehmann
Copy link

I am having the same issue with a bamboo and an instance of my rails 5.0.0.1 app. I already tried app:update, doesn't work.

@ojab
Copy link
Contributor Author

ojab commented Nov 30, 2016

@tfluehmann …and you haven't provided steps to reproduce an issue.

@tfluehmann
Copy link

tfluehmann commented Nov 30, 2016

@ojab sorry for that, I fixed it now by running rails db:environment:set RAILS_ENV=test before each command.
My flow looks now like that:

rails db:environment:set RAILS_ENV=test
rails db:drop RAILS_ENV=test
rails db:environment:set RAILS_ENV=test
rails db:create RAILS_ENV=test

instead of simply:

rails db:drop RAILS_ENV=test
rails db:create RAILS_ENV=test

@mvz
Copy link

mvz commented Dec 2, 2016

@Schwad I solved my previous reproduction by removing the pending migrations check from rails_helper.rb. However, I have another reproduction that cannot be solved this way:

git clone git@github.com:publify/publify_core.git
cd publify_core
git checkout raah2
sh foo.sh

The file foo.sh contains:

bundle exec rake db:migrate RAILS_ENV=test
RAILS_ENV=test bundle exec rake spec # succes
bundle exec rake # succes
RAILS_ENV=test bundle exec rake spec # failure

So the result of the above steps is that the specs are 'run' three times. I added a raise at the top of rails_helper.rb to make the spec abort if it makes it past the actual problem, which manifests itself int the third run, where it outputs:

rake aborted!
ActiveRecord::EnvironmentMismatchError: You are attempting to modify a database that was last run in `development` environment.
You are running in `test` environment. If you are sure you want to continue, first set the environment using:

	bin/rails db:environment:set RAILS_ENV=test

/home/matijs/.rbenv/versions/2.3.1/bin/bundle:23:in `load'
/home/matijs/.rbenv/versions/2.3.1/bin/bundle:23:in `<main>'
Tasks: TOP => app:db:test:load => app:db:test:purge => app:db:check_protected_environments
(See full trace by running task with --trace)

I hope this helps getting to the root of the problem. I'm happy to open a new ticket if you feel this is a different problem.

@andrewyoo
Copy link

andrewyoo commented Dec 14, 2016

I found a solution for myself. Here we go:

I was encountering ActiveRecord::NoEnvironmentInSchemaError with pg and started inspecting my databases.

The key difference I found was my ar_internal_metadata had the column key set as integer on DBs having issues and DBs not having issues key was set to varchar and had a value of environment

Also my schema which was loading was doing this:

create_table "ar_internal_metadata", primary_key: "key", force: :cascade do |t|
  t.string   "value"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

The schema should be like:

create_table "ar_internal_metadata", primary_key: "key", id: :string, force: :cascade do |t|
  t.string   "value"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

Now everything works. Hope this helps others. I'm guessing it got screwed up some how in the rails4 to rail5 migration.

@micahlisonbee
Copy link

@andrewyoo that schema difference was the cause of my issue as well. I deleted that table manually and re-ran rails db:migrate and it resolved itself. Sounds like this issue might need to re-open?

@ojab
Copy link
Contributor Author

ojab commented Jan 14, 2017

It will be helpful if someone will write how you've got wrong column type in schema.

@micahlisonbee
Copy link

@ojab Not sure. I had been switching between Rails 4.2 and 5.0 branches as we are upgrading to 5.0...

@estiens
Copy link

estiens commented Jan 24, 2017

@micahlisonbee @ojab I was also regularly switching between Rails 4.2 and Rails 5 branches as I was working on an upgrade when I encountered this issue -- thanks for sleuthing @andrewyoo !

@JasonBarnabe
Copy link
Contributor

Just to add another potential cause of ActiveRecord::NoEnvironmentInSchemaError... I got this running rake test which executes rspec and cucumber tests (though running each separately did not show the problem). Upgrading cucumber-rails to 1.4.5 and running rails generate cucumber:install fixed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests