2010-11-27 4 views
1

Django의 ORM을 사용하여 많은 양의 데이터를 db에 커밋하는 변환 스크립트를 실행하고 있습니다. 나는 프로세스를 가속화하기 위해 수동 커밋을 사용한다. 커밋 할 파일이 수백 개 있으며, 각 파일은 백만 개 이상의 개체를 생성합니다.django db 업로드 스크립트에서 파이썬 프로세스가 계속 커짐

저는 Windows 7 64 비트를 사용하고 있습니다. 파이썬 프로세스가 800MB 이상을 소비 할 때까지 계속 커지는 것을 보았습니다. 이것은 첫 번째 파일에만 해당됩니다!

스크립트는 텍스트 파일의 레코드를 반복하며 동일한 변수를 사용하고 목록이나 튜플을 누적하지 않습니다.

나는이 파이썬에 대한 일반적인 문제가 있음을 here 읽기 (그리고 아마도 모든 프로그램),하지만 난 여기에

이 개요의 ... 아마도 장고 파이썬 프로세스의 크기를 줄일 수있는 몇 가지 명시적인 방법을 가지고 기대했다 코드 :

import sys,os 
sys.path.append(r'D:\MyProject') 
os.environ['DJANGO_SETTINGS_MODULE']='my_project.settings' 
from django.core.management import setup_environ 
from convert_to_db import settings 
from convert_to_db.convert.models import Model1, Model2, Model3 
setup_environ(settings) 
from django.db import transaction 

@transaction.commit_manually 
def process_file(filename): 
    data_file = open(filename,'r') 

    model1, created = Model1.objects.get_or_create([some condition]) 
    if created: 
     option.save() 

    while 1: 
     line = data_file.readline() 
     if line == '': 
      break 
     if not(input_row_i%5000): 
      transaction.commit() 
     line = line[:-1] # remove \n 
     elements = line.split(',') 

     d0 = elements[0] 
     d1 = elements[1] 
     d2 = elements[2] 

     model2, created = Model2.objects.get_or_create([some condition]) 
     if created: 
      option.save() 

     model3 = Model3(d0=d0, d1=d1, d2=d2) 
     model3 .save() 

    data_file.close() 
    transaction.commit() 

# Some code that calls process_file() per file 

답변

3

우선, 을 settings.py에 입력하십시오. DEBUG=True 일 때 데이터베이스에 전송 된 모든 쿼리는 django.db.connection.queries에 저장됩니다. 많은 레코드를 가져올 경우 많은 양의 메모리로 바뀝니다. 당신은 쉘을 통해 확인할 수 있습니다 :

$ ./manage.py shell 
> from django.conf import settings 
> settings.DEBUG 
True 
> settings.DEBUG=False 
> # django.db.connection.queries will now remain empty/[] 

을 그 다음 수 있도록 각 파일에 대해 process_file을 실행하기 위해 새로운 Process을 산란하지 않는 경우. 이것은 가장 효율적인 것은 아니지만 CPU 사용량을 줄이지 않고 메모리 사용량을 줄이려고합니다. 이 같은 것을 시작해야합니다.

from multiprocessing import Process 

for filename in files_to_process: 
    p = Process(target=process_file, args=(filename,)) 
    p.start() 
    p.join() 
+0

정말 옳았습니다. 처음 실행했을 때 프로세스가 1GB 이상의 메모리를 차지하게되었습니다. DEBUG를 False로 설정하면 프로세스가 스크립트 전체에서 13MB를 유지했습니다. 감사! – Jonathan

0

그것은 말하기 어려운, 제가 제안하는 것은 &이 메모리 서지를 일으키는 코드의 어떤 부분 참조 코드를 프로파일입니다.

코드의 어느 부분이 메모리를 소진하는지 알면 감소시킬 수 있습니다.

메모리 소비가 줄어들지 않아도 처리 할 수 ​​있습니다. 프로세스가 여전히 실행되는 동안 프로세스가 메모리를 할당 받기 때문에 (또는 페이지) &을 릴리스하면 하위 프로세스를 생성 할 수 있으므로, 모든 메모리 집약적 인 작업을 수행하십시오 & 결과를 상위 프로세스 & 다이로 다시 전달하십시오. 이 방법을 사용하면 (자식 프로세스의) 사용 된 메모리가 OS & 부모 프로세스가 마른 상태로 되돌아갑니다 ...

관련 문제