Exporting From Rails on Heroku
Recently I needed to do a bunch of ad-hoc data exports from production. These exports were for exploration, so the format went through a few iterations of change. Using heroku run console
and copy-pasting in a script got tedious, and its hard to capture the output. So here are two better ways of exporting data from a Rails app running on Heroku.
via PostgreSQL
If you want to export some tables, PostgreSQL has a neat built-in feature that can turn a query result into a CSV file. Running queries against the Heroku database can be done via heroku ps:psql
which comes as part of the Heroku CLI. It does require you to have PostgreSQL installed on your local machine.
-- in a file named users.sql
COPY (
SELECT
u.id as "User ID",
u.name as Name,
FROM users u
) TO STDOUT WITH (FORMAT csv, HEADER)
# Write the results of users.sql to a file named users.csv
heroku pg:psql --app=your-app < users.sql > users.csv
via a Rails script
When you are wanting to save the result of a script run with cat script.rb | heroku run rails console
, there are some problems. Namely that the script lines are echo’d into the output. To avoid this, you can use rails runner
.
If you are doing any logging in your script, you might need to set the logger to STDERR, so you can capture the script output and logging output separately.
# users.rb
report = csv.generate do |csv|
csv << headers
User.find_each do |u|
csv << [u.id, u.name]
end
end
STDOUT.puts report
# run the users.rb script and save the result to users.csv
cat users.rb | heroku run --no-tty --app=your-app -- bin/rails runner - > users.csv
# In my case, I need to remove a few NewRelic logging lines that are outputted when the rails console starts up.
cat users.rb | heroku run --no-tty --app=your-app -- bin/rails runner - | grep -v "\*\* \[NewRelic\]" > users.csv