2011-07-27 5 views
0

필자는 CSV 파일에서 읽은 많은 수의 개체를 데이터베이스에 저장하려고합니다. 이것은 내가 뭐하는 거지입니다 :Rails3에서 데이터베이스 배열에 객체 배열을 저장하는 방법은 무엇입니까?

# Read CSV 
... each do |values| 
    new_value = Model.new 
    ... # fill properties 
    @new_values.push new_value # put it into the array 
end 

# now save them to the database 
@new_values.each do |new_value| 
    new_value.save :validate => false 
    @added_counter += 1 
end 

을하지만 배열의 각 요소에 대해 성명을 발표하기 때문에이 정말 느립니다. 이것이 어떻게 빠르고 정확하게 할 수 있습니까?

+0

MySQL을 사용하고 있으며 모델이 만들어지고 CSV 파일 (각각 약 30 개의 정수 또는 부동 소수점)에서 많은 양의 popertys가 생성됩니다. –

+1

AR을 그대로두고 SQL에 직접 가거나 심지어 MySQL이 CSV를 모두 가져 오는 것을 고려한 적이 있습니까? AR은 정확하게 속도 악마가 아닙니다. –

+0

CSV 파일을 읽을 때 데이터 유효성을 검사해야합니다. 왜냐하면 사용자가 CSV 파일을 읽었 기 때문입니다. 그러나 사용자 지정 SQL 문을 작성하는 것은 이동하는 방법처럼 보입니다. 나는 그것을 시도 할 것이다. –

답변

3

activerecord-import이 유용 할 수 있습니다.

그것은 같은 것을 수행 할 수 있습니다 (! 감사합니다)

books = [] 
10.times do |i| 
    books << Book.new(:name => "book #{i}") 
end 
Book.import books 
+0

아 좋은 전에 데이터를 저장하는 임시 DB로 NoSQL 솔루션을 시도해 볼 수 있습니다. 손으로 이것을하는 것보다 훨씬 더 좋음. –

0

무의 의견을 기반으로하는 솔루션은 너무 짧은입니다. 수제 SQL 문을 사용하여 실행합니다.

insert_statement = "INSERT INTO table_name (custom_property_from_parameter" 
    # the properties from the model are fetched by a method, to keep it a little bit generic, loop trough them and give their names to the statement 
    Model.parameter_names.each do |parameter| 
    insert_statement += "," + parameter 
    end 
    insert_statement += ") VALUES " 
    @new_values.each do |new_value| 
    insert_statement += "(" + params[:custom_property] 
    Model.parameter_names.each do |parameter| 
     # Rails' nil has to be converted into NULL for SQL 
     if nil == new_value.send(parameter) 
     insert_statement += ",NULL" 
     else 
     insert_statement += "," + new_value.send(parameter).to_s 
     end 
    end 
    insert_statement += ")," 
    @added_counter += 1 
    end 
    # Remove the last , with ; 
    insert_statement = insert_statement[0..-2] 
    insert_statement += ";" 
    # now execute the statement 
    ActiveRecord::Base.connection.execute insert_statement 

이 해결 방법은 약 3 분의 1이 걸릴 수 있습니다. 하지만 그것은 나에게 해킹처럼 조금 보인다.

+0

이것은 activerecord-import를 사용하여 작성하지 않아도되는 종류의 코드입니다. AR 모델의 열 정의를 기반으로 가져 오는 데이터를 지능적으로 변환합니다. 또한 MAX PACKET ALLOWED 초과 오류를 얻을 수있는 MySQL과 같은 RDBMS에 대해 최소량의 import 문을 실행하도록합니다. –

관련 문제