2014-07-14 2 views
0

예를 들어, 파일에서 읽고 항목을 배열에 추가하고 배열 길이가 1000 이상인 경우 bulk_create을 호출하면 db 1 백만 항목 (400MB 이상)을 추가하려고합니다. 메모리 누수와 스크립트 .. 왜? ..Django - bulk_create에 대한 모델 인스턴스 생성

# python 3 
# models.py 
class Item(models.Model): 
    name1 = models.TextField() 
    name2 = models.TextField() 
    name3 = models.TextField() 
    name4 = models.TextField() 
    name5 = models.TextField() 
    name6 = models.TextField() 
    name7 = models.TextField() 
    name8 = models.CharFiled(max_length=150, unique=True) 

# action 
with open('items.txt') as file_object: 
    items = [] 
    for line in file_object: 
     item_data = line.strip().split(';') 

     i = Item(
      name1=item_data[0], 
      name2=item_data[1], 
      name3=item_data[2], 
      name4=item_data[3], 
      name5=item_data[4], 
      name6=item_data[5], 
      name7=item_data[6], 
      name8=item_data[7], 
      name9=item_data[8], 
     ) 

     items.append(i) 

     if len(items) > 1000: 
      Item.objects.bulk_create(items) 
      del items[:] 

때로는 스크립트 인상 오류

django.db.utils.DatabaseError: Lost connection to MySQL server at '127.0.0.1:3306', system error: 10054

왜? ..


이전에는 SQLAlchemy를 사용하고 있었지만 이러한 문제는 발생하지 않았습니다.

+0

아이디어를 얻을 것이다, 그러나 당신이에 대한 루프 내에서 bulk_create를 호출하고 나에게 보인다,하지만 당신은 아마 원하는 for-loop가 실행 된 후에 호출하는 방법? – kreld

+1

@kreld 하나의 변수에 (100 만 개 이상) 모델 인스턴스를 모두 저장하고 700MB 이상 메모리에로드하면됩니다. 이런 이유로 1000 개의 항목 뒤에'bulk_create'를 호출합니다. –

+0

아마도 for-loop 대신 발전기를 사용할 수 있습니까? –

답변

0

다음과 같이 시도해 볼 수 있습니다. 이 코드를 실행하지 않은하지만 당신은이 오류에 대한 이유가 될 수 없습니다

with open('items.txt') as file_object: 
    num_lines = sum(1 for line in open('items.txt')) 
    def _get_items(): 
     for counter, line in enumerate(file_object): 
      item_data = line.strip().split(';') 

      i = Item(
       name1=item_data[0], 
       name2=item_data[1], 
       name3=item_data[2], 
       name4=item_data[3], 
       name5=item_data[4], 
       name6=item_data[5], 
       name7=item_data[6], 
       name8=item_data[7], 
       name9=item_data[8], 
      ) 
      yield i 
      if counter == 1000: 
       break 

    for i in num_lines/1000: 
     Item.objects.bulk_create(_get_items()) 
관련 문제