关于rails上的ruby:ActiveRecord :: StatementInvalid:PG InFailedSqlTransaction

ActiveRecord::StatementInvalid: PG InFailedSqlTransaction

我正在尝试创建ActiveRecord对象。但创建对象时出现此错误。

1
2
(0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR:  CURRENT TRANSACTION IS       aborted, commands ignored until END OF TRANSACTION block

关于这个问题的任何想法。


其他答案都不能解决问题的根本原因。

问题是,当Postgres引发异常时,它会在同一连接上毒害未来的事务。

修复方法是回滚有问题的事务:

1
2
3
4
5
6
7
8
BEGIN
  ActiveRecord...do something...
rescue Exception => e
  puts"SQL error in #{ __method__ }"
  ActiveRecord::Base.connection.execute 'ROLLBACK'

  raise e
END

参阅参考文献。


我有这个问题。只需重新启动Rails服务器,它就可以工作了


这个问题发生在我的测试环境中,并且是由每个测试都包装在自己的事务中这一事实引起的。

我正在使用数据库清洗器gem,并对其进行配置,以便在使用javascript的情况下不将测试包装到事务中。为了解决这个问题,我在导致这个问题的每个规范中添加了js: true。(即使认为规范实际上没有使用JavaScript,这也是确保测试不会被打包到事务中最方便的方法。不过,我敢肯定,这样做的黑客方法更少了)。

以下是spec/support/database_cleaner.rb中的数据库清洗器配置供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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

如果您不使用数据库清洗器,那么将测试包装在事务中的原因可能是use_transactional_fixtures选项在spec/spec_helper.rb中设置为true。尝试将其设置为false。


你可以在PostgreSQL日志中看到真实的情况,我花了很多时间来研究这个问题,最后发现我们误用了upsert gem导致了pg错误,只有在PostgreSQL日志中才有真实的信息。

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


我在引用规范中不再存在的列时遇到了这个错误。确保您的数据库是最新的,并且您的代码不需要不存在的列。


在我的例子中,/usr/local/var/postgres/postgresql.conf的postgres配置的日期类型是dmy的国际格式。

把datetype改成mdy的美国格式为我解决了这个问题。


在我的例子中,我收到这个错误仅仅是因为我没有整理测试数据库。


问题:

  • 程序执行的SQL语句不正确。错误的SQL语句是问题的根本原因。
  • 程序不会在错误的SQL语句后立即回滚或释放保存点。
  • 程序在错误的SQL语句之后执行SQL语句。
  • PostgreSQL引发错误:当前事务中止,命令被忽略,直到事务块结束
  • 解决方案:

    查找不正确的SQL语句并更正它。如果不想更正SQL语句,请在不正确的SQL语句之后使用回滚或释放保存点。


    我有那个问题。我发现这是我的问题。这意味着当我查询关联而不指定表列时。前任:

    1
    2
    3
    4
    5
    6
    7
    class Holiday < ApplicationRecord
         belongs_to :company
    END

    class Company < ApplicationRecord
        has_many :timeoffs
    END

    在假日模型I查询中

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

    出现错误是因为我没有指定哪个表的id。在我把代码改成

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

    在将Rails从4.2.2升级到4.2.5之后出现了类似的问题,我不得不升级pggem,问题开始出现了。

    1
    2
    3
    4
    5
    6
    7
    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))

    泰迪·寡妇的回答在这个意义上是正确的,只是总结一下问题:

    有时使用DatabaseCleaner.clean_with :deletion时,可能会干扰PostgreSQL事务。

    所以我的解决方案是在部分测试中替换DatabaseCleaner.clean_with :deletion,这些测试是由DatabaseCleaner.clean_with :truncation引起的。

    还有一件事就是谷歌搜索。如果您注意到这个堆栈跟踪:

    1
    2
    3
    4
    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...
    ^

    …可能是这个问题引起的