2012-05-18 5 views
0

Je dois pouvoir comparer deux colonnes de chaque ligne d'un fichier CSV avec ma propre base de données.Importation d'enregistrements à partir d'un fichier CSV et écriture simultanée sur le même fichier CSV?

Par exemple, une ligne ressemble à ceci:

Headers => "Zipcode", "HouseNumber" 
Row 1 => "5435 ZX", "43" 

Tout d'abord je dois trouver une entreprise dans ma propre base de données, basée sur code postal et numéro de maison, et, si cela retourne vrai, alors je dois importer le reste des colonnes dans cette rangée. Je sais comment résoudre ça. Mais, je dois aussi pouvoir garder une trace des lignes importées, parce que j'ai besoin de diviser le total des enregistrements en petits morceaux, donc j'ai besoin d'ajouter un champ supplémentaire à chaque ligne une fois importée.

Pour résumer:

Comment puis-je ajouter un champ supplémentaire (« importé ») à chaque ligne une fois importée dans la boucle suivante:

CSV.foreach('reviews.csv', :headers => true) do |row| 
    Review.create(row.to_hash) 
end 
+0

En relisant la question, la ligne «Je dois diviser le nombre total d'enregistrements en petits morceaux» me dépasse - pourquoi avez-vous besoin de faire cela? Pouvez-vous donner plus de contexte? –

Répondre

0

On dirait que la chose la plus simple à faire serait de maintenir l'état « importé » dans un hachage séparé, comme ceci:

imported = {} 
CSV.read('reviews.csv').each_with_index do |row, line| 
    if <your condition> && !imported[line] 
    # create model 
    imported[line] = true 
    end 
end 

Ensuite, il suffit de garder ce hachage jusqu'à ce que vous devez lire le bloc suivant, et réexécutez. Le bit && !imported[line] empêche la lecture d'une ligne deux fois.

Si ce n'est pas ce que vous cherchez, vous devrez clarifier un peu votre question. :-)

1

Cet extrait de code va créer le Review si vous le pouvez trouver le Company. Vous devrez le nettoyer pour qu'il corresponde aux noms d'attribut corrects pour la table companies.

CSV.foreach('reviews.csv', :headers => true) do |row| 
    Review.create(row.to_hash) if Company.where("Zipcode = ? and HouseNumber = ?", 
     row.Zipcode, row.HouseNumber) 
end 

Pour ajouter une colonne supplémentaire, à ce qui suit:

CSV.foreach('reviews.csv', :headers => true) do |row| 
    if company = Company.where("Zipcode = ? and HouseNumber = ?", 
     row.Zipcode, row.HouseNumber) 
    row[:imported] = true 
    Review.create(row.to_hash) 
end 

Cela suppose la colonne imported existe dans votre table.

Je pense que nous pouvons avoir besoin de plus d'informations pour vous donner une réponse plus complète, mais les idées ici devraient vous rapprocher.

+0

Merci pour la réponse rapide, mais row [: importé] = true (ou une chaîne) ne semble pas fonctionner. J'utilise ceci dans une tâche de rake, mais les champs "importés" dans un ne changent pas. – Laurens

+0

C'est pourquoi je disais que nous avions besoin de plus d'informations. Pouvez-vous poster ce code de modèle? –

+0

Ce n'est pas le code du modèle qui casse ... Même cela échoue: CSV.foreach ('reviews.csv',: headers => true) do | row | ligne [: importé] = "true" fin – Laurens