强制$ rake db:重置尽管其他用户使用Postgres

时间:2013-03-30 15:00:10

标签: ruby-on-rails database postgresql reset

即使Postgres有其他用户使用它,也有办法强制重置数据库。当我尝试$ 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.

2 个答案:

答案 0 :(得分:5)

如果您发现自己在开发过程中经常使用lib/database.rake,请将其放在文件db:reset中。

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

显然仅设计用于非生产数据库。它将导致所有现有数据库连接被切断,因此如果unicorn / passenger / pow正在汇集数据库连接,则下一页加载可能会出错。如果发生这种情况,简单的页面刷新将导致服务器打开一个新的连接,一切都会很好。

答案 1 :(得分:2)

如果连接的会话来自您的rails进程 - 您肯定想要停止rails,如果您从正在运行的进程下面删除并重建db,则可能会发生奇怪的事情

无论如何,可以从命令行运行以下命令来删除postgres连接

psql -c "SELECT pid, pg_terminate_backend(pid) as terminated FROM pg_stat_activity WHERE pid <> pg_backend_pid();" -d 'example_database_name'