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

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

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

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

result = ActiveRecord::Base.connection.execute( @PGSQL_COPY_COMMAND ) # perform the copy command 

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

我错过了什么吗?

您可以使用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) 

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

在pg-0.17.1(Rails 4)中,对Postgres COPY有一个改进的PG::Connection::copy_data接口。

  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 

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

  result = raw.copy_data "COPY my_table FROM STDIN" do raw.put_copy_data File.read(filename) end 

您也可以尝试这个,并使用psql执行命令:

 config = YourApp::Application.config.database_configuration[::Rails.env] dbhost, dbuser, dbname = config['host'], config['username'], config['database'] copy_command = "\\copy theTable (col1, col2, col3) from '/a/path/to/csv' csv header;" sql_command = "psql -U #{dbuser} -h #{dbhost} #{dbname} -c \"#{copy_command}\"" `#{sql_command}`