Процесс Python продолжает расти в сценарии загрузки django db - PullRequest
1 голос
/ 27 ноября 2010

Я запускаю скрипт преобразования, который фиксирует большие объемы данных в БД, используя ORM Джанго. Я использую ручной коммит, чтобы ускорить процесс. У меня есть сотни файлов для фиксации, каждый файл создаст более миллиона объектов.

Я использую Windows 7 64bit. Я заметил, что процесс Python продолжает расти, пока он не потребляет больше 800 МБ, и это только для первого файла!

Скрипт перебирает записи в текстовом файле, повторно используя те же переменные и не накапливая списки или кортежи.

Я прочитал здесь , что это общая проблема для Python (и, возможно, для любой программы), но я надеялся, что, возможно, у Django или Python есть какой-то явный способ уменьшить размер процесса ...

Вот краткий обзор кода:

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

Ответы [ 2 ]

3 голосов
/ 27 ноября 2010

Прежде всего, убедитесь, что DEBUG=False в вашем settings.py.Все запросы, отправленные в базу данных, хранятся в django.db.connection.queries при DEBUG=True.Это превратится в большой объем памяти, если вы импортируете много записей.Вы можете проверить это через оболочку:

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

Если это не поможет, попробуйте создать новый Процесс , чтобы запустить файл_процесса для каждого файла.Это не самый эффективный способ, но вы пытаетесь сократить использование памяти, а не циклы процессора.Как-то так должно начаться:

from multiprocessing import Process

for filename in files_to_process:
    p = Process(target=process_file, args=(filename,))
    p.start()
    p.join()
0 голосов
/ 27 ноября 2010

Трудно сказать, что я хотел бы предложить, это профилировать ваш код и посмотреть, какой раздел вашего кода вызывает этот всплеск памяти.

После того, как вы узнаете, какая часть кода перегружает память, вы можете подумать об ее уменьшении.

Даже после того, как ваши усилия не уменьшают потребление памяти, вы можете сделать это - поскольку процессы получают выделение памяти в виде кусков (или страниц) и освобождают их, пока процесс еще не завершен, вы можете порождать дочерний процесс все ваши задачи, требующие большого объема памяти, передаются в родительский процесс и умирают. Таким образом, использованная память (дочернего процесса) возвращается обратно в ОС, а ваш родительский процесс остается сухим ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...