PG ::错误:另一个命令已在进行中

Jon*_*yco 4 ruby postgresql import activerecord pg

我有一个导入器,它接收电子邮件列表并将它们保存到postgres数据库中.以下是无表导入器类中的代码片段:

query_temporary_table = "CREATE TEMPORARY TABLE subscriber_imports (email CHARACTER VARYING(255)) ON COMMIT DROP;"
query_copy            = "COPY subscriber_imports(email) FROM STDIN WITH CSV;"
query_delete          = "DELETE FROM subscriber_imports WHERE email IN (SELECT email FROM subscribers WHERE suppressed_at IS NOT NULL OR list_id = #{list.id}) RETURNING email;"
query_insert          = "INSERT INTO subscribers(email, list_id, created_at, updated_at) SELECT email, #{list.id}, NOW(), NOW() FROM subscriber_imports RETURNING id;"

conn = ActiveRecord::Base.connection_pool.checkout
conn.transaction do
  raw = conn.raw_connection

  raw.exec(query_temporary_table)
  raw.exec(query_copy)
  CSV.read(csv.path, headers: true).each do |row|
    raw.put_copy_data row['email']+"\n" unless row.nil?
  end
  raw.put_copy_end
  while res = raw.get_result do; end # very important to do this after a copy

  result_delete = raw.exec(query_delete)
  result_insert = raw.exec(query_insert)

  ActiveRecord::Base.connection_pool.checkin(conn)
  {
    deleted:  result_delete.count,
    inserted: result_insert.count,
    updated:  0
  }
end
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,当我尝试上传时,我得到一个例外:

PG::ERROR: another command is already in progress: ROLLBACK
Run Code Online (Sandbox Code Playgroud)

这一切都是在一个动作中完成的,我正在进行的唯一其他查询是用户验证,并且我有一个DB互斥锁防止重叠导入.这个查询工作正常,直到我的最新推送包括将我的pg gem从0.13.2更新到0.14.1(以及其他"无关"代码).

该错误最初是在我们的登台服务器上启动的,但我当时能够在本地重现它并且没有想法.

如果我需要更清楚我的问题,请告诉我.

谢谢

Jon*_*yco 9

找到我自己的答案,如果有人在使用"COPY"导入数据量时发现相同的问题,这可能会有用

在CSV.read()块中抛出异常,我确实抓住了它,但我没有正确地结束该过程.

  begin
    CSV.read(csv.path, headers: true).each do |row|
      raw.put_copy_data row['email']+"\n" unless row.nil?
    end
  ensure
    raw.put_copy_end
    while res = raw.get_result do; end # very important to do this after a copy
  end
Run Code Online (Sandbox Code Playgroud)

此块确保完成COPY命令.我还在最后添加了这个以将连接释放回池中,而不会在成功导入的情况下中断流程:

rescue
  ActiveRecord::Base.connection_pool.checkin(conn)
Run Code Online (Sandbox Code Playgroud)

  • 还有[更完整的例子](https://bitbucket.org/ged/ruby-pg/src/tip/sample/copyfrom.rb)如何在`pg`库的示例中使用原始PG连接执行此操作目录.它添加了错误处理,并显示了您可能希望如何使用从#get_result获得的Result对象. (3认同)