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:create doesn't work #158

Open
unrooty opened this issue Mar 1, 2018 · 23 comments
Open

rails db:create doesn't work #158

unrooty opened this issue Mar 1, 2018 · 23 comments

Comments

@unrooty
Copy link

unrooty commented Mar 1, 2018

I have such error running rails db:create. Can anybody help?

rails aborted!
Sequel::Error: No database associated with Sequel::Model: have you called Sequel.connect or Sequel::Model.db= ?
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/sequel-5.5.0/lib/sequel/model/base.rb:353:in `db'
/home/vladislav/taxi_project_api/config/initializers/sequel.rb:3:in `<main>'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/bootsnap-1.1.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `load'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/bootsnap-1.1.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `load'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:277:in `block in load'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:249:in `load_dependency'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:277:in `load'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/engine.rb:657:in `block in load_config_initializer'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/notifications.rb:170:in `instrument'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/engine.rb:656:in `load_config_initializer'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/engine.rb:614:in `block (2 levels) in <class:Engine>'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/engine.rb:613:in `each'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/engine.rb:613:in `block in <class:Engine>'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/initializable.rb:32:in `instance_exec'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/initializable.rb:32:in `run'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/initializable.rb:61:in `block in run_initializers'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/initializable.rb:50:in `each'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/initializable.rb:50:in `tsort_each_child'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/initializable.rb:60:in `run_initializers'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/application.rb:360:in `initialize!'
/home/vladislav/taxi_project_api/config/environment.rb:5:in `<main>'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/bootsnap-1.1.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/bootsnap-1.1.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `block in require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:249:in `load_dependency'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/application.rb:336:in `require_environment!'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/application.rb:519:in `block in run_tasks_blocks'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/command.rb:48:in `invoke'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/railties-5.2.0.rc1/lib/rails/commands.rb:18:in `<main>'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/bootsnap-1.1.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/bootsnap-1.1.8/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `block in require'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:249:in `load_dependency'
/home/vladislav/.rvm/gems/ruby-2.5.0/gems/activesupport-5.2.0.rc1/lib/active_support/dependencies.rb:283:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:create => environment
(See full trace by running task with --trace)
@SkylerLipthay
Copy link

SkylerLipthay commented Mar 2, 2018

I am guessing on line 3 of initializers/sequel.rb you have something like DB = Sequel::Model.db. If you comment this line out temporarily then rails db:create will work.

I just encountered this problem. It's weird because rails db:drop or rails db:migrate or rails c do not have a problem with that initializer. It's only rails db:create that does not have Sequel::Model.db loaded by the time of the initializer.

@Jesterovskiy
Copy link

Same issue in my project. I use this workaround:

begin
  DB = Sequel::Model.db
  DB.extension :pg_array, :pg_json, :pg_enum
rescue Sequel::Error
end

@bgentry
Copy link

bgentry commented Apr 21, 2018

This happens for me on a brand new Rails project which has no references to Sequel other than the gem 'sequel-rails' bit in the Gemfile.

This is the culprit: it's called in database.rake as part of any task. Ideally these rake tasks would work even if we couldn't preconnect to the specific database.

@unrooty
Copy link
Author

unrooty commented Apr 21, 2018

I found a solution that works in my case.

The error exists because of full environment initialization during the rake task invocation. So when I try to create the database, it loads my initializers, where I have Sequel customization. And even if I place it under the ActiveSupport lazy load hook (on_load(:sequel) do ), trailblazer-loader gem will do force loading of models, which will execute the hook and once again I will catch an error and no database will be created.

So possible solutions is to: 1) don't load all the env for rake task (currently I use this one), 2) to rescue Sequel database errors and force execute createdb commands.

My rake task looks like this:

Rake::Task['db:create'].clear
namespace :db do
  desc 'Create the database defined in config/database.yml for the current Rails.env'
  task :create do
    database_config = {
      Rails.env => Rails.application.config_for('database')
    }
    
    ::SequelRails::Configuration.for(Rails.root, database_config)

    unless SequelRails::Storage.create_environment(Rails.env)
      abort "Could not create database for #{Rails.env}."
    end
  end
end

@bgentry
Copy link

bgentry commented Apr 21, 2018

Digging a little deeper into this, the problem is that the code that decides whether to connect to the database is dependent on ARGV, which appears to always be []. When I placed a debugger there, I saw:

[1] pry(#<SequelRails::Railtie>)> database_connection_required?(app)
=> true
[2] pry(#<SequelRails::Railtie>)> ARGV
=> []

This is true even if I run spring:stop before running the rake task to ensure that no preloader is getting in the way.

@bgentry
Copy link

bgentry commented Apr 21, 2018

In railtie.rb, this initializer is the source of this problem:

    initializer 'sequel.connect' do |app|
      ::SequelRails.setup(::Rails.env) if database_connection_required?(app)
    end

If I change that conditional to if Rails.env.production? the rake tasks all seem to work, and rake -T no longer requires a database connection.

Is there a reason it needs to run at all, or run outside of production?

@bgentry
Copy link

bgentry commented May 1, 2018

So it does seem that we need to call Sequel.connect at some point before actually using the database. The fact that this is done in an initializer and is always run, even for rake tasks, causes a bunch of problems. But I'm not sure there's a better place where this could be done (like at a later stage of Rails initialization or something). I'm not aware of any other hooks in the boot process we could use. Anybody have an idea for how to solve this?

This also causes some issues when attempting to solve #159, because I have to figure out a way to disconnect Sequel before the parallel test processes are forked. Currently the parallel testing support doesn't have any hooks that can be called pre-fork, but one may need to be added to make this compatible with Sequel / sequel-rails.

@ptadros
Copy link

ptadros commented May 22, 2018

So I had the same problem and spent couple of days to figure out the problem and the solution. So basically, Sequel read database configuration directly from config/database.yml. In this case you don't need the initializer at all. What makes sequel to skip using database.yml` and asks you for a database connection if you explicitly skipped database connection in the application startup using the following option

config.sequel.skip_connect = true

If you removed this option and have the correct database config in database.yml, rake db:create will work correctly. Per their docs, they fixed an issue with db:create rake task in version 1.0.1 https://github.com/TalentBox/sequel-rails/blob/master/History.md
I'm using Rails 5, sequel-rails (1.0.1)
I hope this can help anyone faces the same issue.

@bgentry
Copy link

bgentry commented May 22, 2018

If you create a brand new rails app w/ sequel-rails (and no initializer at all) the issue is still present. So it happens even without skip_connect.

@gencer
Copy link

gencer commented Jul 17, 2018

Have the same problem in test environment. I cannot pass tests due to db:create fails. No matter of skip_connect true or false

@unrooty
Copy link
Author

unrooty commented Jul 17, 2018

@gencer, try to use my solution, it should work.

@gencer
Copy link

gencer commented Jul 17, 2018

@unrooty, I just applied your solution. However there is one problem. My application tries to execute an initializer from /initializers/doorkeeper.rb

Let me illustrate with log:

Creating DB  <= This is where your solution start to work. I put this message there.
--
rake aborted!
Sequel::Error: No database associated with Sequel::Model: have you called Sequel.connect or Sequel::Model.db= ?
/var/lib/build-agent/builds/build-1/bp/endpoint/config/initializers/doorkeeper.rb:3:in `<main>'
/var/lib/build-agent/builds/build-1/bp/endpoint/config/environment.rb:5:in `<main>'
/var/lib/build-agent/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/var/lib/build-agent/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
Tasks: TOP => db:drop => environment
(See full trace by running task with --trace)

Do you know how can I make sure this initializers should not executed or at least not complain about my database?

Doorkeeper is using orm :sequel at line 3

@nbulaj
Copy link

nbulaj commented Jul 17, 2018

hi @gencer . @unrooty works with database without loading application env. So it looks strange that you command loads initializers.

Also it is possible that Doorkeeper (or Doorkeeper-Sequel) directly loads Sequel, so it triggers the error (but as far as I remember doorkeeper-sequel uses lazy loading of Sequel gem). You can try to bypass this problem by adding a "top-level" initializer like GitLab does (config/initializers/001_sequel.rb) where you will disable table presence validations. By "top-level" initializer I mean the file that will be loaded first.

@gencer
Copy link

gencer commented Jul 17, 2018

@nbulaj, I tried something like in initializers/001_sequel.rb;

if Rails.env.test?
	::Sequel::Model.require_valid_table = false
end

or just ::Sequel::Model.require_valid_table = false. However, doorkeeper.rb#3 complains about database not table. I still get Sequel::Error: No database associated with Sequel::Model: have you called Sequel.connect or Sequel::Model.db= ? error.

Do you know any method so that doorkeeper-sequel does not complain about my database exists or not.?

Interestingly, db:drop and other tasks just works.

@ptadros
Copy link

ptadros commented Jul 18, 2018

@gencer Have you tried to remove config.sequel.skip_connect = true config completely, remove the initializer and try to run the rake task again?

@gencer
Copy link

gencer commented Jul 18, 2018

@engpeter2010 yes, That was the first thing I tried.

@ptadros
Copy link

ptadros commented Jul 18, 2018

@gencer and which sequel-rails version do you use?

@gencer
Copy link

gencer commented Jul 18, 2018

@engpeter2010 v1.0.1 (latest available at the moment.)

They claim this version has included fixes about db:create. However, one of my initializers (doorkeeper.rb#3 using as orm: sequel) is complaining about my database.

Maybe internally true, however, this is my case.

@ptadros
Copy link

ptadros commented Jul 18, 2018 via email

@kgilpin
Copy link

kgilpin commented Jan 9, 2019

Try enabling extensions only after the DB connection is successfully established, per https://github.com/TalentBox/sequel-rails#enabling-plugins. For example:

Rails.application.config.sequel.after_connect = proc do
  Sequel::Model.db.extension :pg_json
end

@MorneL
Copy link

MorneL commented Apr 29, 2019

Is there any update on this yet?

I am unable to run rake db:create if I have an existing Sequel:model

I'm also getting this error Sequel::Error: No database associated with Sequel::Model: have you called Sequel.connect or Sequel::Model.db= ?
but it doesn't make sense that I have called Sequel.connect as there is no db to connect to.

@JonathanTron
Copy link
Member

Hi @MorneL, what version of Rails are you using?

If you're using Rails >= 5.0, then can you try: rails db:create (instead of rake db:create)?

I don't have any issue on a fresh Rails 5.2 app using sequel-rails if I invoke the command via rails (eg: rake -T -> rails -T, etc).

@gencer
Copy link

gencer commented Apr 30, 2019

@JonathanTron. On fresh installed Rails, there is no problem. I believe @MorneL is using some kind of extension that rely on Sequel (e.g.: sequel-devise or doorkeeper-sequel etc ...). In this case, this error shows up.

nballenger added a commit to ruralinnovation/multi-svc-cartodb that referenced this issue May 7, 2019
Frustratingly, the `bundle exec rake db:create` step is failing, likely
due to a bug in the `sequel-rails` package:

    TalentBox/sequel-rails#158

The workaround seems to be manually creating the database, because
sequel-rails screws something up such that db:create fails due to the
database not existing. Something in the initializers about attempting to
connect to the db prior to actually creating it, but I wasn't able to
ferret it out or successfully implement their supposed fixes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants