我通常使用以下导入模块将数据复制到rails中的postgres数据库中。
在这种情况下,我正在上传一个准备好接受postgres copy命令的文件。
module Import #< ActiveRecord::Base
class Customer
include ActiveModel::Model
include EncodingSupport
attr_accessor :file
validates :file, :presence => true
def process file=nil
file ||= @file.tempfile
ActiveRecord::Base.connection.execute('truncate customers')
conn = ActiveRecord::Base.connection_pool.checkout
raw = conn.raw_connection
raw.exec("COPY customers FROM STDIN WITH (FORMAT CSV, DELIMITER ',', NULL ' ', HEADER true)")
# open up your CSV file looping through line by line and getting the line into a format suitable for pg's COPY...
data = file.open
data::gets
ticker = 0
counter = 0
success_counter = 0
failed_records = []
data.each_with_index do |line, index|
raw.put_copy_data line
counter += 1
end
# 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)
return { :csv => false, :item_count => counter, :processed_successfully => counter, :errored_records => failed_records }
end
我现在有另一个文件需要正确格式化,所以我有另一个模块将它从文本文件转换为csv文件并修剪掉不必要的内容。一旦准备就绪,我想将数据传递给上面的模块并让postgres将它带入数据库。
def pg_import file=nil
file ||= @file.tempfile
ticker = 0
counter = 0
col_order = [:warehouse_id, :customer_type_id, :pricelist_id]
data = col_order.to_csv
file.each do |line|
line.strip!
if item_line?(line)
row = built_line
data += col_order.map { |col| row[col] }.to_csv
else
line.empty?
end
ticker +=1
counter +=1
if ticker == 1000
p counter
ticker = 0
end
end
pg_import data
end
我的问题是'process'方法将数据返回为
"warehouse_id,customer_type_id,pricelist_id\n201,A01,0AA\n201,A02,0AC
这意味着当我将它传递给pg_import时,我无法迭代数据。因为它希望它采用以下格式。
[0] "201,A01,0AA\r\n",
[1] "201,A02,0AC\r\n",
[2] "201,A03,oAE\r\n"
我可以使用什么命令转换字符串数据,以便我可以在
中迭代它 data.each_with_index do |line, index|
raw.put_copy_data line
counter += 1
end
...
可能有一个非常简单的解决方案,但只是期望在没有文件迭代的情况下无法使用put_copy_data ...
答案 0 :(得分:0)
在循环之前和之内通过此过程解决了这个问题。
data = CSV.parse(data)
data.shift
data.each_with_index do |line, index|
line = line.to_csv
raw.put_copy_data line
counter += 1
end
使用csv将字符串转换为数组数组。转移摆脱标题行。这允许我迭代数组。获取一个数组并将该数组从数组转换回csv字符串,然后将其传递到数据库中。