gpt4 book ai didi

ruby - 通过 rake 任务将 CSV 文件上传到 Rails 4 DB

转载 作者:数据小太阳 更新时间:2023-10-29 08:17:25 28 4
gpt4 key购买 nike

我正在尝试使用 rake 任务(rake 数据:导入)从 csv 文件导入数据,但出现错误。在过去的几个月里,我一直在自学 Rails,但经过一天半的谷歌搜索后,我找到了很多解决方案,但没有一个我可以开始工作。

这是我到目前为止的 rake 文件:

require 'CSV'
namespace :data do
desc "Import teams from csv file"
task :import => [:environment] do
file=IO.read('filepath of my csv').force_encoding("ISO-8859-1").encode("utf-8", replace: nil)

CSV.foreach(file, :headers => true) do |row|
product.create ([
:name => row['name'],
:rating => row['rating'],
:year => row['year'],
:country => row['country'],
:state_or_province => row['state_or_province']]
)
end

end
end

我没有收到任何具体错误(据我所知)。令我困惑的输出是:

tasks/dataimport.rake:7:in `block (2 levels) in <top (required)>'

该输出是否表明发生了任何特定的事情?

最佳答案

这里有很多问题,所以我将从头开始。

CSV.foreach旨在打开一个文件并一次遍历它。 CSV.foreach 的第一个参数应该是文件名称,而不是文件的内容。这意味着:

CSV.foreach(file, :headers => true) do |row|

出错是因为 file 是一个包含 CSV 数据的字符串,而不是 CSV.foreach 期望的文件名。由于您要从 Latin-1 文本转换为 UTF-8,因此您需要获取 CSV.foreach 来为您处理,您可以使用 :encoding 选项:

This method also understands an additional :encoding parameter that you can use to specify the Encoding of the data in the file to be read. [...] For example, encoding: "UTF-32BE:UTF-8" would read UTF-32BE data from the file but transcode it to UTF-8 before CSV parses it.

综合起来,我们有:

CSV.foreach('filepath of my csv', :headers => true, :encoding => 'ISO-8859-1:UTF-8') do |row|

一旦开始 CSV 读取和迭代,您将看到如下错误:

NameError: undefined local variable or method `product' for ...

你会得到一个 NameError 因为在你的 rake 任务的任何地方都没有定义 product 。我怀疑您的意思是说 Product.create,它会尝试创建您的 Product 模型的新实例。 Ruby 区分大小写,因此 productProduct 是不同的东西,Product 是类。

处理完 NameError 后,您会看到这样的投诉:

NoMethodError: undefined method `keys' for [{ ... }]:Array

您将得到 NoMethodError,因为 Product.create 想要查看属性及其值的散列,而不是包含散列的数组。你会想说:

Product.create(
:name => row['name'],
:rating => row['rating'],
:year => row['year'],
:country => row['country'],
:state_or_province => row['state_or_province']
)

当然,如果您的 row 仅包含这五个值,则只需将整个 row 交给create:

Product.create(row.to_hash)

如果 row 包含(或可能包含)一堆您不希望 create 看到的其他内容,请使用 Hash#slice仅获取您感兴趣的 row 部分:

Product.create(row.to_hash.slice(*%w[name rating year country state_or_province]))

请注意,%w[...] 从一个以空格分隔的列表构建一个字符串数组,因此它们是相同的:

%w[a b]
['a', 'b']

然后 splat (*) 删除数组包装器,因此它们是相同的:

row.to_hash.slice(*%w[name rating year country state_or_province])
row.to_hash.slice('name', 'rating', 'year', 'country', 'state_or_province')

您可以使用对您的眼睛更舒适的形式。

另请注意 to_hash在那里打电话。您的 row 将是一个 CSV::Row 对象,对其调用 to_hash 将为您提供作为哈希的行。


这应该让您的整个抽取任务看起来像这样:

CSV.foreach('filepath of my csv', :headers => true, :encoding => 'ISO-8859-1:UTF-8') do |row|
Product.create(row.to_hash)
end

CSV.foreach('filepath of my csv', :headers => true, :encoding => 'ISO-8859-1:UTF-8') do |row|
Product.create(row.to_hash.slice(*%w[name rating year country state_or_province]))
end

您可能还想为那些 create 调用添加一些错误处理。

关于ruby - 通过 rake 任务将 CSV 文件上传到 Rails 4 DB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21240297/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com