Python进程在Django数据库上传脚本中不断增长
我正在运行一个转换脚本,这个脚本使用Django的ORM把大量数据存入数据库。我手动提交数据,以加快这个过程。我有几百个文件需要提交,每个文件会创建超过一百万个对象。
我使用的是64位的Windows 7。我注意到Python进程的内存使用量不断增加,直到超过800MB,而这仅仅是处理第一个文件时的情况!
这个脚本会循环读取文本文件中的记录,重复使用相同的变量,并且没有累积任何列表或元组。
我在这里看到,这个问题是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 个回答
0
很难直接说出解决办法,我建议你先分析一下你的代码,看看哪个部分在消耗大量内存。
一旦你找到了那个占用内存的部分,就可以考虑怎么减少它的内存使用。
如果你努力之后,内存使用还是没有减少,可以试试这个方法:因为程序在获取内存时是分块(或者说是以页为单位)来分配的,而在程序运行时释放这些内存是比较困难的。你可以创建一个子进程,把所有需要大量内存的任务放在这个子进程里完成,然后把结果传回给父进程,最后让子进程结束。这样,子进程使用的内存就会归还给操作系统,而你的父进程就能保持轻量。
3
首先,确保你的settings.py文件里有DEBUG=False
。当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。虽然这样不是最有效率的方法,但你主要是想减少内存使用,而不是CPU的使用。可以参考下面的代码开始:
from multiprocessing import Process
for filename in files_to_process:
p = Process(target=process_file, args=(filename,))
p.start()
p.join()