2012-12-07 5 views
0

Lire les données d'un fichier CSV fourni par l'utilisateur d'un nombre inconnu de lignes. J'itérer sur les lignes et plutôt que d'insérer individuellement chaque ligne individuellement dans la base de données (potentiellement un rendement blesser grand nombre d'inserts), je concaténer les valeurs dans une seule chaîne:Désinfecter les données MySQL dans Ruby on Rails 2

insert_values += ", (#{params[:quantity]}, #{'#{params[:name]}', '#{Time.now.to_s(:db)}')" 

je construire ensuite la pleine requête SQL :

sql = "INSERT INTO `my_table` (`quantity`, `name`, `created_at`) VALUES"+insert_values 

Enfin, je l'exécute:

ActiveRecord::Base.connection.execute(sql) 

Je veux rendre les données en toute sécurité de l'injection malveillante. Quelle est la meilleure façon de procéder?

Répondre

0

Merci pour tous les conseils utiles qui m'ont conduit sur mon chemin final. J'ai fini par changer ma chaîne à un tableau de valeurs pour profiter de la méthode intégrée de Rails, sanitize_sql_array après avoir lu another post.

placeholders = [] 
insert_values = [] 

csvrow.each do |row| 
    placeholders << (?,?,?) 
    insert_values << params[:quantity] << #{params[:name]} << {Time.now.to_s(:db) 
end 

query_string = "INSERT INTO `my_table` (`quantity`, `name`, `created_at`) VALUES #{placeholders.join(", ")}"] + insert_values 
sql = ActiveRecord::Base.send(:sanitize_sql_array, query_string) 
ActiveRecord::Base.connection.execute(sql) 
1

Si vous faites cela, vous devez prendre le temps d'échapper à tous les champs entrant dans la base de données en utilisant les méthodes d'échappement de connexion sous-jacentes d'AR. Sinon, vous demandez simplement des ennuis.

Ou ... utiliser quelque chose d'autre qui est destiné à faire beaucoup de volume, mais poignées encore la fuite pour vous ... https://github.com/zdennis/activerecord-import

+0

Malheureusement, Philip, activerecord-est importé pour Rails 3. :( –

+0

rats. Ensuite, vous devez creuser dans 'AR ... connection.escape' pour vous assurer que vous échapper correctement toutes les –

+0

Je prévois de passer à 3 au début de l'année prochaine et j'utiliserai l'importation. –

1

Vous pouvez envisager d'utiliser la syntaxe MySQL LOAD DATA INFILE pour insérer vos données CSV. Il est optimisé pour le téléchargement et ne nécessite pas de créer manuellement une chaîne de requête à risque d'injection.

Voici lien vers MySQL docs:

http://dev.mysql.com/doc/refman/5.6/en/load-data.html

LOAD DATA [LOCAL] INFILE '/path/to/data.csv' 
INTO table 
FIELDS TERMINATED BY ',' ENCLOSED BY '' ESCAPED BY '\' 
LINES TERMINATED BY '\n' 

Remarque utilisation LOCAL si le serveur d'applications et base de données sont sur des machines différentes. Vous devrez peut-être modifier les paramètres de champ et de ligne en fonction du format de votre fichier CSV.