3

I want to give users the option of uploading files in my Ruby on Rails 3.2 application, with the data going into the db. I wanted to use the COPY FROM command since it is faster than inserting ruby objects.

If I do

User.connection.execute("COPY users (name, taxon_id, created_at, updated_at) FROM 'a.txt'")

I get

ActiveRecord::StatementInvalid: PG::Error: ERROR:  must be superuser to COPY to or from a file
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.

However, \copy does not work in a db connection either. How do you easily upload data from flat files in Rails with PostgreSQL on Heroku? Can you get superuser permissions?

1

2 Answers 2

4

Thanks to @PhilipHallstrom's link, I used COPY FROM STDIN like this:

rc = User.connection.raw_connection
rc.exec("COPY users (name, taxon_id, updated_at, created_at) FROM STDIN")
begin
  until rc.put_copy_data( data )
    $stderr.puts "  waiting for connection to be writable..."
    sleep 0.1
  end
rescue Errno => err
  @errmsg = @errmsg + "%s while reading copy data: %s" % [ err.class.name, err.message ]
  error = true
else
  rc.put_copy_end
  while res = rc.get_result
    if (res.result_status != 1)
      error = true
      @errmsg = @errmsg + "Result of COPY is: %s" % [ res.res_status(res.result_status) ]
    end
  end
end
Sign up to request clarification or add additional context in comments.

2 Comments

I don't understand. Where does "data" come from? What format must it be in? Is it an array? String? Is there a loop somewhere where the data is being read?
Get a better idea from where data variable comes from in here: kadrmasconcepts.com/blog/2013/12/15/…
1

You can use the gem https://github.com/diogob/postgres-copy Assuming data is an IO object.

User.copy_from data, columns: [:name, :taxon_id, :updated_at, :created_at]

Or using the path to the uploaded file directly:

User.copy_from "/tmp/uploaded_file.csv", columns: [:name, :taxon_id, :updated_at, :created_at]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.