Postgres将null复制到timestamp列中

时间:2015-01-31 04:51:34

标签: ruby-on-rails postgresql

当我尝试将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

1 个答案:

答案 0 :(得分:1)

这可能是COPY中操作顺序的错误,但在使用CSV格式时,NULL''选项对引用的空字符串没有影响("")。

您有几种方法可以缓解这种情况。修改数据以剥离""这将允许NULL''强制这些列为NULL,或将临时表中的时间戳数据类型更改为文本。然后引用的空字符串将导入而不会出现问题。

要处理空字符串,您需要更改INSERT以使用NULLIF()将空字符串视为NULL,然后将结果转换为{ {1}}输入:

timestamp