在不同的服务器上使用Rails的postgresql COPY命令的问题

NJ.*_*NJ. 8 postgresql ruby-on-rails

我有一个已成功运行数月的rails应用程序.在一些地方,我通过ActiveRecord :: Base.connection.execute(sql_code)直接调用数据库

由于最近需要扩展,我刚刚添加了第二台服务器进行数据处理.我想运行相同的应用程序,但通过网络连接到其他数据库服务器.这是唯一的区别.应用程序的所有其他区域都可以工作 - 它可以连接到远程数据库.

它破坏的地方,是我有rails的地方发出psql COPY命令来导入csv文件.

   result = ActiveRecord::Base.connection.execute( @PGSQL_COPY_COMMAND )     # perform the copy command
Run Code Online (Sandbox Code Playgroud)

这失败并说无法找到csv文件.我已经验证它在那里,并且对于运行rails app和postgres用户的用户都是可读的.

我错过了什么吗?

Phi*_*rom 21

您可以使用COPY FROM STDIN来解决这个问题......就像这样:

conn = ActiveRecord::Base.connection_pool.checkout
raw  = conn.raw_connection
raw.exec("COPY tablename (col1, col2, col3) FROM STDIN")
# open up your CSV file looping through line by line and getting the line into a format suitable for pg's COPY...
raw.put_copy_data line
# once all done...
raw.put_copy_end
while res = raw.get_result do; end # very important to do this after a copy
ActiveRecord::Base.connection_pool.checkin(conn)
Run Code Online (Sandbox Code Playgroud)

我相信COPY有一些选项可以让你指定你传递CSV数据,这会让它更容易......

  • 使用例如`res.result_status`和`res.error_message`来提及如何使用和处理错误会很酷. (2认同)

hyb*_*aut 12

在pg-0.17.1(Rails 4)中PG::Connection::copy_data,Postgres COPY的界面有了改进.

  def load_file(filename)

    dbconn = ActiveRecord::Base.connection_pool.checkout
    raw  = dbconn.raw_connection
    count = nil

    result = raw.copy_data "COPY my_table FROM STDIN" do

      File.open(filename, 'r').each do |line|
        raw.put_copy_data line
      end

    end

    count = dbconn.select_value("select count(*) from #{ttable}").to_i

    ActiveRecord::Base.connection_pool.checkin(dbconn)

    count
  end
Run Code Online (Sandbox Code Playgroud)

如果您不担心内存使用情况,甚至可以将整个文件缓冲区传递给put_copy_data:

      result = raw.copy_data "COPY my_table FROM STDIN" do
        raw.put_copy_data File.read(filename)
      end
Run Code Online (Sandbox Code Playgroud)

  • 如果你使用它并看到它在开发中工作但不在测试中,这可能是因为测试在事务中运行,因此检出的连接对事务是盲目的.所以,试试`dbconn = ActiveRecord :: Base.connection`instead (3认同)