Rails从csv创建表,列名中包含特殊字符

时间:2016-08-29 22:41:04

标签: mysql ruby-on-rails ruby activerecord

我有一个CSV文件,我试图加载到rails数据库。一切正常,直到它到达名为BW (MB)的列。我认为这是括号的问题,因为其他标题有空格而且它们没问题。如果可能的话,我想避免重命名原始CSV文件中的标题。

代码:

CSV.foreach(csv_file, :headers => true) do |row|
    Sevonedatum.create!(row.to_hash.slice('Date', 'Market Area', 'BW (MB)'))
end

错误输出:

  

ActiveRecord :: MultiparameterAssignmentErrors:分配多参数属性时出错1次[赋值错误[&#34; 96.26&#34;]为BW(未定义方法`BW =&#39; for#)] < / p>

您可以看到MultiparameterAssignment错误在将值分配给BW时指向一个问题,但错误中它错过了(MB)部分。< / p>

从迁移文件:

class CreateSevonedata < ActiveRecord::Migration[5.0]
def change
create_table :sevonedata do |t|

t.column :'Date', :date
t.column :'Market Area', :string
t.column :'BW (MB)', :float
t.timestamps
  end
 end
end

2 个答案:

答案 0 :(得分:0)

列名中不能有括号:Rails会尝试将列名“BW(MB)”映射到有效的Ruby属性名称,并且不允许使用括号。空格转换为下划线确定,但不允许使用括号。

看看Active Record如何convention over configuration - Rails的关键原则之一。

Rails允许你做一些覆盖,但你不能有一个“BW(MB)”列等同于一个有效的Ruby类属性。

您有两个选项 - 您需要将这两个选项更改为“BW”。

选项1:编辑CSV文件的标题,使其与列名匹配,并相应地更改代码。

选项2:按标题保留标题,但编写其他代码以将“BW(MB)”替换为“BW”

CSV.foreach(csv_file, :headers => true) do |row|
  foo = row.to_hash.slice('Date', 'Market Area', 'BW (MB)')
  foo["BW"] = foo["BW (MB)"]
  foo.delete("BW (MB)")
  Sevonedatum.create!(foo)
end

(你可以把它优化到更少的线 - 我说它是冗长的,因为你说你是初学者)

答案 1 :(得分:0)

I ended up using the header_converters to convert the headers by utilizing :symbol to convert everything to downcase and remove everything except numbers, letters, and add underscore between spaces. I then modified my database column names to match.

CSV.foreach(csv_file, :headers => true, :header_converters => [:symbol] ) do |row|
Sevonedatum.create!(row.to_hash.slice('market_area', 'date', 'interface', 'peak_period_downlink_util', 'bw_mb'))
    end