PG::Error 将字符串列更改为时间数据类型时的时区

PG::Error timezone when changing string column to time data type

我需要更改列数据类型,目前这些列是字符串,但我需要将其更改为 "time"。

迁移文件:

def change
  change_column :enquiries, :start_time, :time
  change_column :enquiries, :end_time, :time
end

错误信息:

PG::Error: ERROR: column "start_time" cannot be cast automatically to type time without time zone HINT: You might need to specify "USING start_time::time without time zone".

经过一些搜索,我找到了这个解决方案,但它仍然无法正常工作,但是我收到了新的错误消息。

def change
  change_column :enquiries, :start_time, 'time USING CAST(start_time AS time)'
  change_column :enquiries, :end_time, 'time USING CAST(end_time AS time)'
end

PG::Error: ERROR: invalid input syntax for type time: ""

我尝试了 matthewd 解决方案,但仍然无效。

change_column :enquiries, :start_time, "time USING CAST(NULLIF(start_time, '') AS time)"

PG::Error: ERROR: invalid input syntax for type time: "09.00"

请问如何解决?

第二个错误是由于现有行在您的 *_time 列之一中将空白字符串作为其值引起的:正如它所说,这不是 time 类型的有效输入。

最合理的选择是将它们转换为 NULL,您可以使用 NULLIF SQL 函数:

change_column :enquiries, :start_time, "time USING CAST(NULLIF(start_time, '') AS time)"

基本上,这就是我所做的。有很多 start_time 和 end_time 记录,这两列没有验证,所以有些记录格式不正确 (HH:MM)。 但是,需要重构这段代码,但这对我有用。

def up
  rename_column :enquiries, :start_time, :start_time_old
  rename_column :enquiries, :end_time, :end_time_old
  add_column :enquiries, :start_time, :time
  add_column :enquiries, :end_time, :time

  Enquiry.reset_column_information
  Enquiry.find_each do |e| 
    unless e.start_time_old.blank?
      if e.start_time_old.include?('.')
        e.update_column(:start_time , e.start_time_old.gsub('.', ':'))
      else
        e.update_column(:start_time , e.start_time_old)
      end
    end
  end

  Enquiry.find_each do |e| 
    unless e.end_time_old.blank?
      if e.end_time_old.include?('.')
        e.update_column(:end_time , e.end_time_old.gsub('.', ':'))
      else
        e.update_column(:end_time , e.end_time_old)
      end
    end
  end

  remove_column :enquiries, :start_time_old
  remove_column :enquiries, :end_time_old
end