在rails3迁移中,“PGError:错误:当前事务被中止”

时间:2011-09-01 08:51:18

标签: ruby-on-rails postgresql transactions migration rails-migrations

我在Rails 3.0.9下,使用Ruby 1.9.2(p290)。 使用Postgresql 9.0.4和'pg'gem v0.11.0

问题是:

我有一个非常简单的迁移只是用条件改变列的值:

def self.up
  Closet.reset_column_information
  say_with_time "Unifying gender column to h/f" do
    Closet.connection.update "UPDATE closets AS c SET gender='h' WHERE c.gender IN ('homme', 'Homme', 'men', 'Men');"
    Closet.connection.update "UPDATE closets AS c SET gender='f' WHERE c.gender IN ('femme', 'Femme', 'women', 'Women');"
  end
end

每个请求在我的erb控制台和pgAdmin SQL控制台中都能正常运行,但是当我运行迁移时它会说:

PGError: ERROR:  current transaction is aborted, commands ignored until end of transaction block

如果有人作为一个想法...

以下是错误消息堆栈的更大部分:

== MigrateClosets:迁移========================================== ======= 耙子流产了! 发生错误,此操作和所有后​​续迁移都已取消:

PGError: ERROR:  current transaction is aborted, commands ignored until end of transaction block
: UPDATE closets SET gender='h' WHERE closets.gender  = 'homme';
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract_adapter.rb:207:in `rescue in log'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract_adapter.rb:199:in `log'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/postgresql_adapter.rb:514:in `execute'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract/database_statements.rb:288:in `update_sql'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/postgresql_adapter.rb:525:in `update_sql'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract/database_statements.rb:49:in `update'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/connection_adapters/abstract/query_cache.rb:16:in `update'
/Users/gdurelle/Sites/rails/DressMeNextGen/db/migrate/20110613125139_migrate_closets.rb:4:in `up'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/migration.rb:314:in `block in migrate'
/Users/gdurelle/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/benchmark.rb:295:in `measure'
/Users/gdurelle/.rvm/gems/ruby-1.9.2-p290@dressmeNG/gems/activerecord-3.0.9/lib/active_record/migration.rb:314:in `migrate'

1 个答案:

答案 0 :(得分:2)

以下是一些可能有所帮助的疯狂猜测。看起来你有一个交易中止,被抓住,并在某处被忽略;这可能会导致self.up运行的整个事务陷入混乱,这将解释您的错误消息和您所看到的行为。

在数据库更改之后,reset_column_information调用通常会 ,并且只有在架构发生更改且您需要使用新架构进行其余迁移时才会进行调用。这些都不适用于您,因此您可以完全放弃Closet.reset_column_information

您还应该在迁移中使用execute方法,因此根本不需要与Closet通信。此外,在SQL语句的末尾不需要分号;他们可能不会受到伤害,但如果我们将这一点剥离到最基本的要点,我们可能会让问题消失。

试试这个,看看会发生什么:

def self.up
  say_with_time "Unifying gender column to h/f" do
    execute %q{UPDATE closets SET gender = 'h' WHERE gender IN ('homme', 'Homme', 'men', 'Men')}
    execute %q{UPDATE closets SET gender = 'f' WHERE gender IN ('femme', 'Femme', 'women', 'Women')}
  end
end

这为我们提供了更新数据库所需的最低限度。希望流浪交易问题与你不需要的所有其他东西一起消失。