web-dev-qa-db-ja.com

ActiveRecord :: StatementInvalid:PG InFailedSqlTransaction

ActiveRecordオブジェクトを作成しようとしていますが、作成中にこのエラーが発生しています。

(0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR:  current transaction is       aborted, commands ignored until end of transaction block

問題に関するアイデアの人々。

65
untwal

他の回答はどれも、根本的な原因を修正しません。

問題は、Postgresが例外を発生させると、同じ接続で将来のトランザクションをポイズニングすることです。

修正は、問題のあるトランザクションをロールバックすることです。

begin
  ActiveRecord...do something...
rescue Exception => e
  puts "SQL error in #{ __method__ }"
  ActiveRecord::Base.connection.execute 'ROLLBACK'

  raise e
end

参照 を参照してください。

91
B Seven

この問題がありました。 Railsサーバーを再起動するだけで動作します

79
Furkan Ayhan

この問題は私のテスト環境で発生しており、各テストが独自のトランザクションでラップされているという事実が原因でした。

私はdatabase_cleaner gemを使用していましたが、javascriptを使用する場合、トランザクションでテストをラップしないように設定しました。そこで、この問題を解決するために、この問題を引き起こしていた各仕様にjs: trueを追加しました。 (仕様では実際にjavascriptを使用していないと思っていたとしても、これはテストがトランザクションにラップされないようにするための最も便利な方法でした。

参考のために、spec/support/database_cleaner.rbのdatabase_cleaner設定を以下に示します。

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with :deletion
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :deletion
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

Database_cleanerを使用していない場合、おそらくテストがトランザクションにラップされる理由は、use_transactional_fixturesオプションがspec/spec_helper.rbtrueに設定されているためです。 falseに設定してみてください。

14
Teddy Widom

postgresqlログで実際に何が起こっているのかを見ることができます、私はこの問題を掘り下げるのに多くの時間を費やし、最終的にupsert gemを誤用してPGエラーを引き起こすことを発見しました

https://github.com/seamusabshere/upsert/issues/39

8
William Herry

仕様に含まれていない列を参照すると、このエラーが発生しました。データベースが最新であり、コードが存在しない列を予期していないことを確認してください。

5
lobati

私の場合、テストデータベースをすくい取っていないという理由だけで、このエラーを受け取りました。

2
nfriend21

問題:

  1. プログラムは誤ったSQLステートメントを実行します。不正なSQLステートメントが問題の根本原因です。
  2. プログラムは、誤ったSQLステートメントの直後にROLLBACKまたはRELEASE SAVEPOINTしません。
  3. プログラムは、誤ったSQLステートメントの後にSQLステートメントを実行します。
  4. PostgreSQLはエラーを発生させます:現在のトランザクションは中止され、トランザクションブロックの終わりまでコマンドは無視されます

溶液:

誤ったSQLステートメントを見つけて修正します。 SQLステートメントを修正したくない場合は、誤ったSQLステートメントの後にROLLBACKまたはRELEASE SAVEPOINTを使用してください。

2
John Doe

私の場合、/usr/local/var/postgres/postgresql.confは、dmyの国際形式としてdatetypeを持ちました

Datetypeをmdyのアメリカ形式に変更すると、この問題は修正されました。

2
Winsor

Rails 4.2.2から4.2.5にアップグレードした後、同様の問題がありました。pg gemをアップグレードしなければならず、問題が発生し始めました

9) WorkPolicy#is_publicly_viewable? is publicly visible hides work if deleted
     Failure/Error: before { DatabaseCleaner.clean_with :deletion }
     ActiveRecord::StatementInvalid:
       PG::InFailedSqlTransaction: ERROR:  current transaction is aborted, commands ignored until end of transaction block
       :             SELECT tablename
                   FROM pg_tables
                   WHERE schemaname = ANY (current_schemas(false))

Teddy Widom Answer は、この意味で正しい、問題を要約するだけです:

DatabaseCleaner.clean_with :deletionを使用すると、PostgreSQLトランザクションに干渉する場合があります。

だから私にとっての解決策は、DatabaseCleaner.clean_with :deletionでこれが引き起こされたテストの一部でDatabaseCleaner.clean_with :truncationを置き換えることでした

グーグルの人のためにもう一つだけ。このスタックトレースに気づいた場合:

An error occurred in an `after(:context)` hook.
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "table_rows" does not exist
LINE 1: ...ion_schema.tables WHERE table_schema = 'test' AND table_rows...
^

...この問題が原因である可能性があります

0
equivalent8

私はその問題を手に入れました。そして、それが私の質問であることがわかりました。テーブル列を指定せずに関連付けを使用してクエリを実行することを意味します。例:

class Holiday < ApplicationRecord
     belongs_to :company
end

class Company < ApplicationRecord
    has_many :timeoffs
end

Holidayモデルでクエリ

company.timeoffs.where("(start_date <= ? and end_date >= ?) and id != ?", begin_date, begin_date, 1)

エラーが発生するのは、どのテーブルのidを指定しなかったためです。

company.timeoffs.where("(start_date <= ? and end_date >= ?) and time_offs.id != ?", begin_date, begin_date, 1)
0
pdkpro