Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable prepared statement in heroku with postgres database

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

test:
  prepared_statements: false

The bug that I fixed was related to this issue:

 PG::ProtocolViolation: ERROR: bind message supplies 2 parameters, but prepared            statement "a24" requires 1 

Now, I want to fix it on my production app hosted on Heroku with a postgres database. I don't know how to disable prepared statement as the database.yml is automatically generated. I tried to append:

/database?prepared_statements=false

to my database's URI but it ends up with a DATABSE_URL that is wrong and so I can't connect to my database.

What is the process and the right syntax to disable prepared_statement?

like image 542
Solene Maitre Avatar asked Apr 02 '14 13:04

Solene Maitre


People also ask

What is PostgreSQL prepared statement?

A prepared statement is a server-side object that can be used to optimize performance. When the PREPARE statement is executed, the specified statement is parsed, analyzed, and rewritten. When an EXECUTE command is subsequently issued, the prepared statement is planned and executed.


3 Answers

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.

like image 185
Benjamin Hutton Avatar answered Sep 28 '22 08:09

Benjamin Hutton


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 %>
like image 23
markquezada Avatar answered Sep 28 '22 06:09

markquezada


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.

like image 38
lobati Avatar answered Sep 28 '22 06:09

lobati