How to disable prepared statement in heroku with postgres database

后端 未结 6 1109
-上瘾入骨i
-上瘾入骨i 2021-02-20 12:13

I fixed an issue on my rails project locally (with postgres config) while adding in database.yml this statement:

test:
  prepared_statements: false
相关标签:
6条回答
  • 2021-02-20 12:29

    As of Feb 19th 2014, heroku no longer overrides database.yml so you can turn off prepared statements in your production and staging (or default) block of the database.yml file as recommended by the latest docs:

    default: &default
      adapter: postgresql
      encoding: unicode
      pool: 5
      prepared_statements: false
    
    development:
      <<: *default
      database: myapp_development
    
    test:
      <<: *default
      database: myapp_test
    
    production:
      <<: *default
      url:  <%= ENV['DATABASE_URL'] %>
      pool: <%= ENV['DB_POOL'] || ENV['MAX_THREADS'] || 5 %>
    
    staging:
      <<: *default
      url:  <%= ENV['DATABASE_URL'] %>
      pool: <%= ENV['DB_POOL'] || ENV['MAX_THREADS'] || 5 %>
    
    0 讨论(0)
  • 2021-02-20 12:31

    turning off prepared statements decreases performance because postgresql has to replan every query before executing so i do not suggest to turn it off for production servers - especially as rails is notorious for doing many small queries when you don't take really good care about eager loading everything. I suggest indead figuring out how to do restarts in live after each deployment without affecting the availability of your service. I am not a rails guru but i know that it's doable (our company does it exactly like that). Here is a bit more insight into why this is happening https://github.com/rails/rails/issues/12330

    0 讨论(0)
  • 2021-02-20 12:32

    We were worried about brittleness and maintaining consistency between staging/production (using DATABASE_URL on Heroku) and development/test (using database.yml/database.example.yml).

    Inspired by Rails' tests, we put this in config/initializers/disable_prepared_statements.rb:

    ActiveRecord::Base.establish_connection(
      ActiveRecord::Base.remove_connection.merge(
        :prepared_statements => false
      )
    )
    

    remove_connection returns a hash of the connection parameters of the connection being removed. This should let any database.yml or DATABASE_URL continue working.

    0 讨论(0)
  • 2021-02-20 12:32

    You should just be able to add ?prepared_statements=false to the existing database url and restart your dynos. This worked for us.

    heroku config:add DATABASE_URL=[old database url here]?prepared_statements=false
    

    To check that it's set after restarting your server you can open a console and query ActiveRecord::Base.connection_config.

    0 讨论(0)
  • You can pass in a configuration hash to ActiveRecord::Base.establish_connection, in an initializer. For example:

    configure :production, :development, :test do
      db = URI.parse(ENV['DATABASE_URL']
    
      ActiveRecord::Base.establish_connection(
          :adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
          :host                => db.host,
          :username            => db.user,
          :password            => db.password,
          :database            => db.path[1..-1],
          :encoding            => 'utf8',
          :prepared_statements => false,
      )
    end
    

    http://apidock.com/rails/ActiveRecord/Base/establish_connection/class

    0 讨论(0)
  • 2021-02-20 12:45

    Recently it seems that Heroku has disabled setting DATABASE_URL using heroku config:set DATABASE_URL=<blah>?prepared_statements=false, giving us back an error " ▸ Cannot overwrite attachment values DATABASE_URL."

    In order to resolve this, we added an disabled_prepared_statements.rb initializer in config/ containing:

    ActiveRecord::Base.configurations[Rails.env].merge!(prepared_statements: false)

    0 讨论(0)
提交回复
热议问题