6

我正在尝试将种子数据从 CSV 文件加载到我的 Rails 应用程序中。我最初安装了 fastcsv gem,只是发现从 ruby​​ 1.9 开始,fastcsv 已被弃用,取而代之的是 CSV 库。因此,在收到一个非常有用的错误告诉我切换后,我切换到了 CSV。

然而,现在我遇到了最奇怪的现象,当我加载数据时,一切看起来都很正常,但我似乎无法查询字符串字段。字符串字段由看似正确的字符串填充,但我无法访问它们。我可以查询任何数字字段,结果将返回,但不是字符串字段。我尝试使用分隔符来引用引号,但无济于事。我什至从我的 csv 文件中删除了所有引号,但我仍然无法查询字符串字段。下面是我的代码,以及来自 Rails 控制台的一些示例查询和返回。

# seeds.rb
# ================

require 'csv'

directory = "db/init_data/"

file_name = "players.seed"
path_to_file = directory + file_name
puts 'Loading Player records'
# Pre-load All Player records
n=0
CSV.foreach(path_to_file) do |row|
  Player.create! :first_name => row[1], :last_name => row[2], :position_id => row[5], :weight => row[6], :height => row[7], :year => row[8], :home_state => row[9], :home_town => row[10], :home_country => row[11], :high_school_id => row[12], :name => row[13]      
n=n+1
end

这是我的种子文件中的前两条记录。

# players.seed
"1","Allerik","Freeman","2011-10-11 22:21:21.230247","2011-10-11 22:21:21.230247","2","210","76","2013","NC","Charlotte","USA","1","Allerik Freeman"
"2","Kasey","Hill","2011-10-11 22:21:21.262409","2011-10-11 22:21:21.262409","1","170","73","2013","FL","Eustis","USA","2","Kasey Hill"

这就是我进入 rails 控制台时得到的。例如,如果我想查询像 year 这样的数字,它工作得很好。

ruby-1.9.2-p290 :002 > Player.find_all_by_year(2013)
  Player Load (0.7ms)  SELECT "players".* FROM "players" WHERE "players"."year" = 2013
 => [#<Player id: 1, first_name: "Allerik", last_name: "Freeman", created_at: "2011-10-12 20:52:16", updated_at: "2011-10-12 20:52:16", position_id: 2, weight: 210, height: 76, year: 2013, home_state: "NC", home_town: "Charlotte", home_country: "USA", high_school_id: 1, name: "Allerik Freeman">, #<Player id: 2, first_name: "Kasey", last_name: "Hill", created_at: "2011-10-12 20:52:16", updated_at: "2011-10-12 20:52:16", position_id: 1, weight: 170, height: 72, year: 2013, home_state: "FL", home_town: "Eustis", home_country: "USA", high_school_id: 2, name: "Kasey Hill">]

但是,如果我尝试通过说姓氏进行查询,我什么也得不到,即使它告诉我姓氏存在于上一个查询中。

ruby-1.9.2-p290 :004 > Player.find_all_by_last_name("Freeman")
  Player Load (0.3ms)  SELECT "players".* FROM "players" WHERE "players"."last_name" = 'Freeman'
 => [] 

我可以让它工作的唯一方法是使用散列变量表示法将它放在一组额外的双引号(转义)中,这将我的所有字符串记录都放在引号中的数据库中,然后我使用删除命令删除引号退出。

  n=0
  CSV.foreach(path_to_file) do |row|
    Player.create! :first_name => "\"#{row[1]}\"", :last_name => "\"#{row[2]}\"", :position_id => row[5], :weight => row[6], :height => row[7], :year => row[8], :home_state => "\"#{row[9]}\"", :home_town => "\"#{row[10]}\"", :home_country => "\"#{row[11]}\"", :high_school_id => row[12], :name => "\"#{row[13]}\""      
    n=n+1
  end
  puts "There\'s too many playas to hate, we just loaded #{n} of \'em"

  @players = Player.all
  @players.each do |player|
    fname = player.first_name
    player.first_name = fname.delete("\"")
    lname = player.last_name
    player.last_name = lname.delete("\"")
    pcity = player.home_town
    player.home_town = pcity.delete("\"")
    pst = player.home_state
    player.home_state = pst.delete("\"")
    pcountry = player.home_country
    player.home_country = pcountry.delete("\"")
    pname = player.name
    player.name = pname.delete("\"")
    player.save!
  end  

然后我可以查询字符串数据。

ruby-1.9.2-p290 :005 > Player.find_all_by_last_name("Freeman")
  Player Load (0.6ms)  SELECT "players".* FROM "players" WHERE "players"."last_name" = 'Freeman'
 => [#<Player id: 1, first_name: "Allerik", last_name: "Freeman", created_at: "2011-10-12 20:52:16", updated_at: "2011-10-12 20:52:16", position_id: 2, weight: 210, height: 76, year: 2013, home_state: "NC", home_town: "Charlotte", home_country: "USA", high_school_id: 1, name: "Allerik Freeman">, #<Player id: 59, first_name: "Austin", last_name: "Freeman", created_at: "2011-10-12 20:55:16", updated_at: "2011-10-12 20:55:16", position_id: 2, weight: 210, height: 76, year: 2007, home_state: "MD", home_town: "Hyattsville", home_country: "USA", high_school_id: nil, name: "Austin Freeman">] 

显然这不是首选方法,因为它使我的加载时间增加了一倍,但老实说,我无计可施。

任何帮助将不胜感激。

按照这里的要求,我添加了 schema.rb

# schema.rb
# ===================
# encoding: UTF-8
# ...

ActiveRecord::Schema.define(:version => 20111007214728) do

#...

  create_table "players", :force => true do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "position_id"
    t.integer  "weight"
    t.integer  "height"
    t.integer  "year"
    t.string   "home_state"
    t.string   "home_town"
    t.string   "home_country"
    t.integer  "high_school_id"
    t.string   "name"
  end

# ...

end

这是我的 SQLite 数据库浏览器按要求查看的数据库屏幕截图。

玩家表视图:看起来很正常吧?

查询字符串字段时没有返回行

看起来在 ruby​​ 论坛中有一个类似的问题,它可能与编码有关,但我需要对编码做更多的研究才能弄清楚这一点。

4

3 回答 3

2

尝试# encoding: UTF-8在 player.seed 的最顶部添加

# encoding: UTF-8
# players.seed
...
于 2012-09-10T23:31:04.520 回答
0

请检查以下内容:

  • 数据库中字符串的编码,例如它应该是 UTF-8

    你是如何创建数据库的?在 MySQL 中,你应该使用这样的东西:

    创建数据库 DatabaseName DEFAULT CHARACTER SET utf8;

  • 解析/读取 CSV 文件时从 CSV 文件中获取的字符串的编码

见:http ://www.ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html

您还可以尝试直接读取 CSV 文件,以在从文件中读取字符串时检查字符串的编码。


编辑:

一些消息来源说 SQLite 仅支持 ISO-8859-1 编码,并且仅支持 UTF-8(如果在编译时指定).. 这可能是一个问题。您使用哪个版本的 SQLite? http://refdb.sourceforge.net/manual/ch08s09.html

另一方面,这个消息来源说 SQLite 3.x 使用 UTF-8 http://www.sqlite.org/version3.html

于 2011-10-13T01:30:36.500 回答
0

尝试将“# coding: utf-8”添加到seeds.rb 的第一行

# coding: utf-8
# seeds.rb
# ================
...
于 2011-10-17T01:00:41.303 回答