2011-10-13 13 views
6

Sto provando a caricare i dati seme nell'applicazione Rails da un file CSV. Inizialmente ho installato la gem di fastercsv, solo per scoprire che fastcsv è stato deprecato a favore della libreria CSV a partire da Ruby 1.9. Così sono passato a CSV dopo aver ricevuto un errore molto utile che mi diceva di passare.Utilizzo di Ruby CSV crea record Rails in cui i campi stringa non sono interrogabili

Ora, tuttavia, sto ottenendo il fenomeno più strano in cui quando carico i miei dati tutto sembra normale, ma non riesco a interrogare i campi stringa. I campi stringa sono popolati da quelle che sembrano essere le stringhe corrette, ma non posso accedervi. Posso interrogare su uno qualsiasi dei campi numerici, e i risultati torneranno, ma non i campi stringa. Ho provato a giocare con il delimitatore per le virgolette, ma senza risultato. Ho persino spogliato tutte le citazioni dal mio file CSV, ma ancora non ho potuto interrogare i campi stringa. Di seguito è riportato il mio codice e alcune query e ritorni di esempio dalla console di 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 

Ecco i primi due record del mio file seme.

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

Questo è ciò che ottengo quando accedo alla console di rotaie. Funziona bene se voglio interrogare un numero come l'anno, ad esempio.

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

Ma se provo ad interrogare per dire il cognome, non ottengo niente, anche se mi dimostra che il cognome è presente sul query precedente.

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

L'unico modo ho potuto farlo funzionare è stato quello di metterlo in un ulteriore set di virgolette doppie (sfuggito) utilizzando la notazione variabile hash, che ha ottenuto tutti i miei dischi stringa nel database di citazioni, allora Ho usato un comando delete per rimuovere le virgolette.

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 

Quindi ho potuto interrogare i dati di stringa.

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

Ovviamente questo non è un metodo preferito, come è raddoppiato il mio tempo di caricamento, ma ero sinceramente alla fine del mio ingegno.

Qualsiasi aiuto sarebbe molto apprezzato.

come richiesto qui ho aggiunto la 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 

Qui ci sono le immagini del database come visto dalla mia SQLite Database Browser come richiesto.

View of Player Table: Looks normal right?

No Rows Returned when querying a string field

sembra che non v'è a similar issue here in the ruby forums, e che probabilmente ha qualcosa a che fare con la codifica, ma avrò bisogno di fare molto di più ricerche sulla codifica di conoscere questo numero su.

+0

potete inviare i vostri schema.rb? –

+1

Mostraci anche una selezione direttamente dal database dopo il primo caricamento, in modo che possiamo vedere le stringhe senza ActiveRecord nel modo. Il mio istinto è un problema di codifica. – bfabry

+0

Appena aggiunto lo schema.rb e gli screenshot di selezione direttamente dal database, nessun record è stato restituito anche quando si andava direttamente contro il db. –

risposta

0

controllare quanto segue:

  • la codifica delle stringhe nel database, per esempioprobabilmente dovrebbe essere UTF-8

    come hai creato il tuo database? In MySQL dovresti usare qualcosa come:

    creare database DatabaseName SET DI CARATTERI PREDEFINITI utf8;

  • la codifica delle stringhe che si ottiene dal file CSV quando si analizza/leggerlo

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

Si potrebbe anche provare a leggere direttamente il file CSV di verificare la codifica delle stringhe quando vengono letti dal file.


edit:

Alcune fonti dicono che SQLite supporta solo la codifica ISO-8859-1, e solo UTF-8 se è specificato al momento della compilazione .. che potrebbe essere un problema. Quale versione di SQLite usi?http://refdb.sourceforge.net/manual/ch08s09.html

D'altra parte, questa fonte dice che SQLite 3.x utilizza UTF-8 http://www.sqlite.org/version3.html

+0

Non ci sono, per quanto a mia conoscenza, problemi con l'uso di virgolette per la quotazione CSV. La maggior parte degli esempi posso trovare usare le virgolette – bfabry

+0

Il database è stato creato tramite il comando rails new con Rails standard 3.1 e un backend SQLite. –

+0

Ho riscontrato lo stesso problema quando ho rimosso tutti i doppi qoutes. –

0

Prova ad aggiungere "# codifica: utf-8" per la prima riga del seeds.rb

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

Purtroppo non funziona. –

2

Prova ad aggiungere # encoding: UTF-8 al vertice della players.seed

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

Ho provato anche quello, grazie, apprezzo il suggerimento. –

Problemi correlati