0

我试图做一个直接加载到Rails中的PostgreSQL表。我的连接建立这样的:如何使用Rails ActiveRecord一次运行两个数据库命令?

rc = connection.raw_connection 
    rc.exec("COPY research FROM STDIN WITH CSV HEADER") 

下面是代码的一部分:

for key,values in valuehash 
     entry = standard.model_constant::ATTRIBUTE_HASH[key.to_sym] 
     puts "Loading #{entry[:display]}..." 
     values.each do |value| 
     id = ActiveRecord::Base.connection.execute("select nextval('research_id_seq'::regclass)").first['nextval'] 

     line = [id, value, entry[:display], standard.id, now, now] 
     until rc.put_copy_data(line.to_csv) 
      ErrorPrinter.print " waiting for connection to be writable..." 
      sleep 0.1 
     end 
     end 
    end 

开头id =失败的线。它说:

ActiveRecord::StatementInvalid: PG::UnableToSend: another command is already in progress 

我不想把所有这些值写入一个CSV文件,然后读入该文件。我只是想将内存中的数据发送到数据库。我想不出为什么我不能在同一个表上运行两个连接到同一个数据库的有效理由,所以我想我一定是做错了什么。我已经尝试了两个原始连接,但它始终不断地向我提供来自池的相同连接。

+0

你不得不亲自问自己身份证的顺序,这很奇怪。如果插入记录并且不包含id字段,则该序列应该自动填充。 – 2014-10-11 21:40:18

+0

对于id行,为什么你不使用'rc'连接来获取id?或者,为什么不为表创建模型,以便您可以使用标准ActiveRecord插入到数据库中?如果您担心速度问题,可以使用https://github.com/zdennis/activerecord-import – johnsorrentino 2014-10-11 23:46:10

+0

Don - 在直接插入时,您必须提供序列,不存在自动增量。 约翰,我先试了一下。当你这样做时,它会终止COPY命令。不过,我会检查activerecord-import,谢谢。 – AKWF 2014-10-12 01:14:15

回答

1

处理此问题的最佳方法是让数据库为您插入序列号,而不是尝试获取并添加它们。

假设你的表的定义是这样的:

CREATE TABLE research (
    id SERIAL, 
    value TEXT, 
    ... 
) 

则表的定义,例如,如果你插入一行,并且没有指定ID值,则默认的值从序列自动。这与其他形式的插入行同样适用于COPY。

诀窍是确保你没有提供价值。为此,请构造COPY命令,以便不包含id列:

COPY research(value,....) FROM STDIN WITH CSV HEADER 

即,您必须指定您将提供数据的字段列表以及您将提供数据的顺序。

请注意,即使您有一个标题,也不会在导入时使用它来确定存在的列或其顺序。标题被丢弃。

假设您更改了COPY语句,那么您只需从要构建的值数组中删除该ID以发送到数据库。

相关问题