(这是我对于红宝石/铁轨和编程新手必不可少的一行;也是第一个SO问题)
我有一项rake任务,可以从CSV-
...
CSV.read(uri).each do |row|
Incident.create(
:building_address => row[9],
:agency => row[3],
:complaint_type => row[6],
:descriptor => row[5],
:created => row[1],
:closed => row[2],
)
end
:created和:closed被定义为日期字段(并且也与rails created_at和updated_at字段分离/不相关),但是我假设CSV文件仅识别字符串。
当我运行此任务时,一天和一个月都会切换。因此,CSV中的1/12/2010 12:00:00 AM(对于CSV和我本人在美国表示1月12日)最终被解析为2010-12-1,并且12以后的任何一天都返回null,因此1/20/2010 12:00:00 AM在我的数据库。
我加了
date:
formats:
default:"%m/%d/%Y"
到我的en.yml,但这似乎仅影响日期的显示,并且对通过rake任务创建对象没有影响。搜索了SO和其他资源之后,我尝试了
:created => row[1].strftime,
和
:created => row[1].strptime,
但得到了undefined method strptime/strftime for"Created Date":String(创建日期是CSV中列的名称)。
所以我也试过
:created => row[1].to_date
将CSV中的(大概)"日期"字符串更改为日期,但出现错误undefined method '
更改CSV中的日期字段似乎很困难,因为有100万条以上的记录。
如何编辑此rake任务,以从该CSV正确植入我的数据库?还是应该将:created从日期更改为字符串并在应用程序逻辑中对其进行操作?
您可以尝试使用DateTime.strptime将字符串转换为DateTime实例:
:created => DateTime.strptime(row[1], '%m/%d/%Y %H:%M:%S %p'),
:closed => DateTime.strptime(row[2], '%m/%d/%Y %H:%M:%S %p')
strptime类方法将使您可以准确指定所使用的格式,从而使该软件无需猜测。 我建议您将来使用内部使用的ISO 8601日期和时间格式,而将歧义格式留给人类使用。
昨晚尝试了此操作并进行了一些更改,但始终出现invalid date错误。我想也许是因为:created和:closed是Date类而不是DateTime,但是更改没有帮助。今晚将继续尝试,同时还将详细阅读您链接到的ruby文档。
@sbauch::created和:closed列是什么类型?它们是date,datetime还是timestamp?如果它们是日期,则尝试Date.strptime(row[1], %m%d%Y)和Date.strptime(row[2], %m%d%Y)忽略一天中的时间。
我都尝试过。现在,我在控制台中都将两列都设为date,并且能够使用Date.strptime(12152010 12:00 AM, %m%d%Y)(直接从csv复制该日期)。但是在rake任务上仍然出现invalid date错误。
@sbauch:哪个抱怨"日期无效",date或Incident?
看来我的CSV标头在搞糊涂了。谢谢您的帮助!编辑-尽管我认为我已经弄明白了,但是如何说呢?我正在获取invalid date UsersSam.rvmrubiesruby-1.9.2-p290libruby1.9.1date.rb:1022:in new_by_frags
@sbauch:好酷。当您Date.strptime无法解析字符串时,会引发ArgumentError异常;因此您可以添加rescue ArgumentError => e并记下e中的内容。