Skip to content

Instantly share code, notes, and snippets.

@lfittl
Last active March 24, 2017 22:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lfittl/5db2bb2405ebfde77a937b43c65d9169 to your computer and use it in GitHub Desktop.
Save lfittl/5db2bb2405ebfde77a937b43c65d9169 to your computer and use it in GitHub Desktop.
Helper method to use Postgres' COPY with ActiveRecord
# Put this in config/initializers/copy_from_client.rb
class CopyFromClientHelper
attr_reader :count
def initialize(conn, column_types)
@count = 0
@conn = conn
@column_types = column_types
end
def <<(row)
row = row.map.with_index { |val, idx| @column_types[idx].type_cast_for_database(val) }
@conn.put_copy_data(row)
@count += 1
end
end
module CopyFromClient
def self.copy_from_client(columns, &block)
conn = connection.raw_connection
column_types = columns.map { |c| columns_hash[c.to_s] }
helper = CopyFromClientHelper.new(conn, column_types)
conn.copy_data %{COPY #{quoted_table_name}("#{columns.join('","')}") FROM STDIN}, PG::TextEncoder::CopyRow.new do
block.call helper
end
helper.count
end
end
if defined?(ActiveRecord::Base)
ActiveRecord::Base.send(:include, CopyFromClient)
end
MyModel.copy_from_client [:column1, :column2, :column3] do |copy|
copy << ['abc', 123, { json: 'is supported' }]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment