2011-10-13 5 views
6

CSV 파일에서 Rails 애플리케이션에 시드 데이터를로드하려고합니다. 초기에 fastercsv 젬을 설치했는데, 단지 fastercsv가 루비 1.9에서 CSV 라이브러리에 찬성하여 사용되지 않음을 알았습니다. CSV로 전환 했으므로 전환하는 데 매우 도움이되는 오류가 발생했습니다.Ruby CSV를 사용하면 문자열 필드를 질의 할 수없는 곳에서 Rails 레코드가 생성됩니다.

그러나 이제 모든 데이터가로드 될 때 정상적으로 보이지만 문자열 필드를 쿼리 할 수없는 이상한 현상이 발생합니다. 문자열 필드는 올바른 문자열로 표시된 것으로 채워지지만 액세스 할 수는 없습니다. 숫자 필드에 대해 쿼리 할 수 ​​있으며 결과는 반환되지만 문자열 필드는 반환되지 않습니다. 구분 기호를 사용하여 따옴표로 연주 해 보았지만 아무 소용이 없었습니다. 나는 심지어 내 csv 파일에서 모든 따옴표를 제거했지만 여전히 문자열 필드에 대해 쿼리 할 수 ​​없습니다. 아래는 내 코드와 몇 가지 샘플 쿼리 및 Rails Console의 반환입니다.

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

이것은 레일 콘솔에 들어가는 순간입니다. 예를 들어 연도와 같은 숫자를 쿼리하려면 잘 작동합니다. 내가 성을하여 쿼리 말을하려고하면 그것이 마지막 이름은 이전 쿼리에 존재한다는 것을 나에게 보여줍니다에도 불구하고

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' 
=> [] 

유일한 방법은, 인용의 데이터베이스에 내 모든 문자열 기록을 가지고 해시 변수 표기법을 사용하여 큰 따옴표 (탈출)의 추가 세트에 넣어했다 따옴표를 지우려면 delete 명령을 사용했습니다.

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 

그럼 문자열 데이터를 쿼리 할 수 ​​있습니다.

분명히 이것은 내로드 시간이 두 배가되기 때문에 선호되는 방법은 아니지만 솔직히 내 재치에 달렸습니다.

도움을 주시면 감사하겠습니다.

으로 내가 여기 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 데이터베이스 브라우저에서 볼 때 데이터베이스의 스크린 샷입니다했습니다 여기에 요청했다. 이 a similar issue here in the ruby forums이며, 그것은 아마 인코딩 함께 할 수있는 뭔가가 같은

View of Player Table: Looks normal right?

No Rows Returned when querying a string field

그것은 보이지만, 나는이 그림 인코딩에 더 많은 연구를해야합니다 아웃.

+0

당신이 당신의 schema.rb를 게시 할 수 players.seed의 맨 위에 # encoding: UTF-8을 추가? –

+1

또한 첫 번째로드 후에 데이터베이스에서 직접 select를 표시하므로 그 동안 ActiveRecord가없는 문자열을 볼 수 있습니다. 내 본능은 인코딩 문제입니다. – bfabry

+0

데이터베이스에서 직접 선택한 스키마의 schema.rb 및 스크린 샷을 추가 했으므로 db에 대해 직접 실행해도 레코드가 반환되지 않습니다. –

답변

0

다음을 확인

  • 데이터베이스에서 문자열의 인코딩, 예를 들어,아마도 UTF-8이어야합니다.

    데이터베이스를 어떻게 만들었습니까? MySQL에서는 다음과 같이 사용해야합니다 :

    데이터베이스 생성 데이터베이스 이름 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 버전을 사용합니까? "# 코딩 : UTF-8"한편 http://refdb.sourceforge.net/manual/ch08s09.html

,이 소스 SQLite는 3.x를 추가 할 UTF-8 http://www.sqlite.org/version3.html

+0

CSV 인용에 큰 따옴표를 사용하는 것과 관련된 문제는 알고 있습니다. 대부분의 예제에서 큰 따옴표를 사용할 수 있습니다 – bfabry

+0

데이터베이스는 표준 레일즈 3.1과 SQLite 백엔드를 사용하여 새로운 명령을 레일스를 통해 만들었습니다. –

+0

모든 이중 qout을 제거했을 때 같은 문제가 발생했습니다. –

0

에 한번 사용 말한다 당신의 seeds.rb의 첫 번째 라인을

# coding: utf-8 
# seeds.rb 
# ================ 
... 
+0

그래도 작동하지 않습니다. –

2

시도

# encoding: UTF-8 
# players.seed 
... 
+0

나는 그 점을 또한 시험해 보았습니다. 감사합니다. –