Search code examples
ruby-on-railsdatabasepostgresqlreset

Force $ rake db:reset Despite Other Users with Postgres


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.

Solution

  • 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.