ActiveRecordオブジェクトを作成しようとしていますが、作成中にこのエラーが発生しています。
(0.1ms) ROLLBACK
ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block
問題に関するアイデアの人々。
他の回答はどれも、根本的な原因を修正しません。
問題は、Postgresが例外を発生させると、同じ接続で将来のトランザクションをポイズニングすることです。
修正は、問題のあるトランザクションをロールバックすることです。
begin
ActiveRecord...do something...
rescue Exception => e
puts "SQL error in #{ __method__ }"
ActiveRecord::Base.connection.execute 'ROLLBACK'
raise e
end
参照 を参照してください。
この問題がありました。 Railsサーバーを再起動するだけで動作します
この問題は私のテスト環境で発生しており、各テストが独自のトランザクションでラップされているという事実が原因でした。
私は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.rb
のtrue
に設定されているためです。 falseに設定してみてください。
postgresqlログで実際に何が起こっているのかを見ることができます、私はこの問題を掘り下げるのに多くの時間を費やし、最終的にupsert gemを誤用してPGエラーを引き起こすことを発見しました
仕様に含まれていない列を参照すると、このエラーが発生しました。データベースが最新であり、コードが存在しない列を予期していないことを確認してください。
私の場合、テストデータベースをすくい取っていないという理由だけで、このエラーを受け取りました。
問題:
溶液:
誤ったSQLステートメントを見つけて修正します。 SQLステートメントを修正したくない場合は、誤ったSQLステートメントの後にROLLBACKまたはRELEASE SAVEPOINTを使用してください。
私の場合、/usr/local/var/postgres/postgresql.conf
は、dmy
の国際形式としてdatetypeを持ちました
Datetypeをmdy
のアメリカ形式に変更すると、この問題は修正されました。
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...
^
...この問題が原因である可能性があります
私はその問題を手に入れました。そして、それが私の質問であることがわかりました。テーブル列を指定せずに関連付けを使用してクエリを実行することを意味します。例:
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)