Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force $ rake db:reset Despite Other Users with Postgres [duplicate]

Is there a way to force a database reset even if Postgres has other users using it. I almost always get this error when I try a $ rake db:reset:

 Couldn't drop example_database_name :
 #<ActiveRecord::StatementInvalid: PG::Error: ERROR:  database "example_database_name" is being accessed by other users DETAIL: 
 There are 2 other session(s) using the database.
like image 416
Undistraction Avatar asked Sep 07 '25 06:09

Undistraction


2 Answers

Put this in a file lib/database.rake if you find yourself using db:reset a lot in development.

require 'active_record/connection_adapters/postgresql_adapter'
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      def drop_database(name)
        raise "Nah, I won't drop the production database" if Rails.env.production?
        execute <<-SQL
          UPDATE pg_catalog.pg_database
          SET datallowconn=false WHERE datname='#{name}'
        SQL

        execute <<-SQL
          SELECT pg_terminate_backend(pg_stat_activity.pid)
          FROM pg_stat_activity
          WHERE pg_stat_activity.datname = '#{name}';
        SQL
        execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
      end
    end
  end
end

Obviously only designed for use on non-production databases. It will cause all existing db connections to be severed, so the next page load might be an error if unicorn/passenger/pow is pooling db connections. If this happens, a simple page refresh will cause the server to open a new connection and all will be well.

like image 86
Chris Aitchison Avatar answered Sep 10 '25 00:09

Chris Aitchison


if the connected sessions are from your rails process - you definitely want to stop rails, strange things could occur if you drop and rebuild the db from underneath the running process

anyhow the following can be run from the command line to drop postgres connections

psql -c "SELECT pid, pg_terminate_backend(pid) as terminated FROM pg_stat_activity WHERE pid <> pg_backend_pid();" -d 'example_database_name'
like image 43
house9 Avatar answered Sep 10 '25 00:09

house9