当我尝试将csv文件中的空invalid input syntax for type timestamp
列复制到Postgres表中时,我正在关注this question以解析end_at
。
建议的最后一个答案(我正在运行4.2 Rails应用程序)我创建临时表,我将其复制为字符串字段,然后使用临时表数据INSERT INTO真实表。因为我会做很多这样的事情,我只是运行了一个迁移来保持一个永久的temp_table(我在每次导入后都会截断)。我的代码如下,但我无法弄清楚如何在end_at列上执行INSERT INTO,以便空字符串作为空时间戳来实现。
任何提示都会很棒。
def pg_import data
ActiveRecord::Base.connection.execute("truncate temp_pricelist_price_groups")
ActiveRecord::Base.connection.execute("truncate pricelist_price_groups")
conn = ActiveRecord::Base.connection_pool.checkout
raw = conn.raw_connection
raw.exec("COPY temp_pricelist_price_groups (
pricelist_id,
price_group_id,
uom_id,
quantity,
price,
disc_dollar,
disc_percent,
price_flag,
gross_or_net,
start_at,
end_at
) 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...
ticker = 0
counter = 0
success_counter = 0
failed_records = []
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
# once all done...
raw.put_copy_end
raw.exec("INSERT INTO pricelist_price_groups
SELECT *
FROM temp_pricelist_price_groups)")
while res = raw.get_result do; end # very important to do this after a copy
postgresql_error_message = raw.error_message
ActiveRecord::Base.connection_pool.checkin(conn)
ActiveRecord::Base.connection.execute('truncate temp_pricelist_price_groups')
return { :csv => false, :item_count => counter, :processed_successfully => counter, :errored_records => failed_records, :error_message => postgresql_error_message }
end
答案 0 :(得分:1)
这可能是COPY
中操作顺序的错误,但在使用CSV格式时,NULL''选项对引用的空字符串没有影响("")。
您有几种方法可以缓解这种情况。修改数据以剥离""这将允许NULL''强制这些列为NULL,或将临时表中的时间戳数据类型更改为文本。然后引用的空字符串将导入而不会出现问题。
要处理空字符串,您需要更改INSERT
以使用NULLIF()
将空字符串视为NULL
,然后将结果转换为{ {1}}输入:
timestamp