Me gustaría importar datos de un archivo CSV a una tabla de base de datos existente. No quiero guardar el archivo CSV, solo tomar los datos y ponerlo en la tabla existente. Estoy usando Ruby 1.9.2 y Rails 3.
Esta es mi mesa:
create_table "mouldings", :force => true do |t|
t.string "suppliers_code"
t.datetime "created_at"
t.datetime "updated_at"
t.string "name"
t.integer "supplier_id"
t.decimal "length", :precision => 3, :scale => 2
t.decimal "cost", :precision => 4, :scale => 2
t.integer "width"
t.integer "depth"
end
¿Me puede dar un código para mostrarme la mejor manera de hacer esto, gracias.
ruby-on-rails
csv
import
más fresco
fuente
fuente
Versión más simple de la respuesta de yfeldblum, que es más simple y funciona bien también con archivos grandes:
No hay necesidad de with_indifferent_access o symbolize_keys, y no es necesario leer primero el archivo en una cadena.
No mantiene todo el archivo en la memoria a la vez, sino que se lee línea por línea y crea un moldeado por línea.
fuente
La
smarter_csv
gema se creó específicamente para este caso de uso: para leer datos del archivo CSV y crear rápidamente entradas en la base de datos.Puedes usar la opción
chunk_size
para leer N csv-rows a la vez, y luego usar Resque en el bucle interno para generar trabajos que crearán los nuevos registros, en lugar de crearlos de inmediato, de esta manera puede distribuir la carga de generar entradas a múltiples trabajadores.Ver también: https://github.com/tilo/smarter_csv
fuente
Puedes probar
Upsert
:Si esto es lo que desea, también puede considerar deshacerse de la clave primaria de incremento automático de la tabla y establecer la clave primaria en
name
. Alternativamente, si hay alguna combinación de atributos que forman una clave primaria, úsela como selector. No es necesario un índice, solo lo hará más rápido.fuente
Esto puede ayudar También tiene ejemplos de código:
http://csv-mapper.rubyforge.org/
O para una tarea de rastrillo para hacer lo mismo:
http://erikonrails.snowedin.net/?p=212
fuente
Es mejor envolver el proceso relacionado con la base de datos dentro de un
transaction
bloque. El fragmento de código es un proceso completo de envío de un conjunto de idiomas al modelo de idioma,El fragmento a continuación es parcial del
languages.csv
archivo,fuente
Use esta gema: https://rubygems.org/gems/active_record_importer
Entonces ahora puede usar:
Solo asegúrese de que sus encabezados coincidan con los nombres de columna de su tabla
fuente
La mejor manera es incluirlo en una tarea de rastrillo. Cree el archivo import.rake dentro de / lib / task / y coloque este código en ese archivo.
Después de eso ejecuta este comando en tu terminal
rake csv_model_import[file.csv,Name_of_the_Model]
fuente
Sé que es una pregunta antigua, pero todavía está en los primeros 10 enlaces en Google.
No es muy eficiente guardar filas una por una porque causa una llamada a la base de datos en el bucle y es mejor evitarlo, especialmente cuando necesita insertar grandes porciones de datos.
Es mejor (y significativamente más rápido) usar inserción por lotes.
Puede compilar dicha consulta manualmente y luego hacerlo
Model.connection.execute(RAW SQL STRING)
(no recomendado) o usar gemactiverecord-import
(se lanzó por primera vez el 11 de agosto de 2010) en este caso, simplemente coloque los datos en la matrizrows
y llameModel.import rows
consulte los documentos de gemas para más detalles
fuente
Es mejor usar CSV :: Table y usar
String.encode(universal_newline: true)
. Convierte CRLF y CR a LFfuente
Si quieres usar SmartCSV
Esto representa datos delimitados por tabuladores en cada fila
"\t"
con filas separadas por nuevas líneas"\n"
fuente