Cucumber and RSpec testing with zeus: Postgres is being accessed by other users
在我的Rails 3.2.13应用程序中,我正在使用Zeus。 在测试环境中我使用PostgreSQL。 当我运行Cucumber然后运行RSpec(或其他方式)时,10次中有9次我收到消息:
1 2 3 4 5 6 | PG::Error: ERROR: DATABASE"bp_test" IS being accessed BY other users DETAIL: There are 1 other SESSION(s) USING the DATABASE. : DROP DATABASE IF EXISTS"bp_test" Tasks: TOP => db:test:LOAD => db:test:purge (See FULL trace BY running task WITH --trace) |
如此处所述,尝试杀死数据库连接以使其再次工作需要一个完整的非确定性马戏团。 但这并不总是有效,也是一个很大的麻烦。 必须有一个更好的解决方案。 有人知道吗?
受此答案的启发,我们创建了以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #{Rails.root}/lib/tasks/DATABASES.rake # monkey patch ActiveRecord TO avoid There are n other SESSION(s) USING the DATABASE. def drop_database(config) CASE config['adapter'] WHEN /mysql/ ActiveRecord::Base.establish_connection(config) ActiveRecord::Base.connection.drop_database config['database'] WHEN /sqlite/ require 'pathname' path = Pathname.new(config['database']) file = path.absolute? ? path.to_s : File.join(Rails.root, path) FileUtils.rm(file) WHEN /postgresql/ BEGIN ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x| IF config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/ ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})") END END ActiveRecord::Base.connection.drop_database config['database'] rescue # IN PG 9.2 COLUMN procpid was renamed pid AND the query STATUS IS checked NOT USING 'current_query' but USING 'state' ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by pid;").each do |x| IF config['database'] == x['datname'] && x['state'] =~ /idle/ ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['pid']})") END END ActiveRecord::Base.connection.drop_database config['database'] END END END |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | namespace :db do DESC 'Clear the database' task :clear_db => :environment do |t,args| ActiveRecord::Base.establish_connection ActiveRecord::Base.connection.tables.each do |TABLE| NEXT IF TABLE == 'schema_migrations' ActiveRecord::Base.connection.execute("TRUNCATE #{table}") END END DESC 'Delete all tables (but not the database)' task :drop_schema => :environment do |t,args| ActiveRecord::Base.establish_connection ActiveRecord::Base.connection.execute("DROP SCHEMA public CASCADE") ActiveRecord::Base.connection.execute("CREATE SCHEMA public") ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO postgres") ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO public") ActiveRecord::Base.connection.execute("COMMENT ON SCHEMA public IS 'standard public schema'") END DESC 'Recreate the database and seed' task :redo_db => :environment do |t,args| # Executes the dependencies, but ONLY once Rake::Task["db:drop_schema"].invoke Rake::Task["db:migrate"].invoke Rake::Task["db:migrate:status"].invoke Rake::Task["db:structure:dump"].invoke Rake::Task["db:seed"].invoke END END |