6

CSV ファイルからシード データを Rails アプリケーションにロードしようとしています。最初にfasterscsv gemをインストールしましたが、ruby 1.9の時点でfasterscsvが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

シード ファイルの最初の 2 つのレコードを次に示します。

# 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 コンソールに入ると得られるものです。たとえば、年のような数値を照会したい場合は問題なく動作します。

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">] 

読み込み時間が 2 倍になるため、明らかにこれは好ましい方法ではありませんが、正直なところ、私は頭がいっぱいでした。

どんな助けでも大歓迎です。

ここで要求されたように、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-8player.seed の一番上に追加してみてください

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

以下を確認してください。

  • データベース内の文字列のエンコーディング。たとえば、おそらく UTF-8 である必要があります

    どのようにデータベースを作成しましたか? MySQL では、次のようなものを使用する必要があります。

    データベースを作成 DatabaseName DEFAULT CHARACTER SET utf8;

  • 解析/読み取り時に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

「# コーディング: utf-8」を、seeds.rb の最初の行に追加してみてください。

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