Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加快Django表单将大型(500k obs)CSV文件上载到MySQL数据库_Python_Mysql_Django_Csv - Fatal编程技术网

Python 加快Django表单将大型(500k obs)CSV文件上载到MySQL数据库

Python 加快Django表单将大型(500k obs)CSV文件上载到MySQL数据库,python,mysql,django,csv,Python,Mysql,Django,Csv,Django表约为430000 obs和230mb文件\ 它来自一个平面CSV文件,在下面的\ 模特。我考虑过在CSV阅读器中使用块,但我认为处理器\ 填充MySQL表的函数是我的挂起;需要20个小时+\ 我怎样才能加快速度 class MastTable(models.Model): evidence = models.ForeignKey(Evidence, blank=False) var2 = models.CharField(max_length=10, blank=T

Django表约为430000 obs和230mb文件\ 它来自一个平面CSV文件,在下面的\ 模特。我考虑过在CSV阅读器中使用块,但我认为处理器\ 填充MySQL表的函数是我的挂起;需要20个小时+\ 我怎样才能加快速度

class MastTable(models.Model):
    evidence = models.ForeignKey(Evidence, blank=False)
    var2 = models.CharField(max_length=10, blank=True, null=True)
    var3 = models.CharField(max_length=10, blank=True, null=True)
    var4 = models.CharField(max_length=10, blank=True, null=True)
    var5 = models.CharField(max_length=10, blank=True, null=True)
    var6 = models.DateTimeField(blank=True, null=True)
    var7 = models.DateTimeField(blank=True, null=True)
    var8 = models.DateTimeField(blank=True, null=True)
    var9 = models.DateTimeField(blank=True, null=True)
    var10 = models.DateTimeField(blank=True, null=True)
    var11 = models.DateTimeField(blank=True, null=True)
    var12 = models.DateTimeField(blank=True, null=True)
    var13 = models.DateTimeField(blank=True, null=True)
    var14 = models.CharField(max_length=500, blank=True, null=True)
    var15 = models.CharField(max_length=500, blank=True, null=True)
    var16 = models.CharField(max_length=50, blank=True, null=True)
    var17 = models.CharField(max_length=500, blank=True, null=True)
    var18 = models.CharField(max_length=500, blank=True, null=True)
    var19 = models.CharField(max_length=500, blank=True, null=True)
    var20 = models.CharField(max_length=500, blank=True, null=True)
    var21 = models.CharField(max_length=500, blank=True, null=True)
    var22 = models.CharField(max_length=500, blank=True, null=True)
    var23 = models.DateTimeField(blank=True, null=True)
    var24 = models.DateTimeField(blank=True, null=True)
    var25 = models.DateTimeField(blank=True, null=True)
    var26 = models.DateTimeField(blank=True, null=True)
此帮助函数将为CSV创建一个读卡器对象\ 在上传MySQL之前,还要对文件中的任何时髦的编解码器进行解码

def unicode_csv_reader(utf8_data, dialect=csv.excel, **kwargs):
    csv_reader = csv.reader(utf8_data, dialect=dialect, **kwargs)
    for row in csv_reader:
        yield [unicode(cell, 'ISO-8859-1') for cell in row]
然后,UTILS.PY文件中的函数将访问一个DB表(名为'extract_properties'),该表\ 包含用于标识要转到哪个处理器函数的文件头\ 处理器功能如下所示

def processor_table(extract_properties):  #Process the table into MySQL
    evidence_obj, created = Evidence.objects.get_or_create(case=case_obj, 
    evidence_number=extract_properties['evidence_number']) #This retrieves the Primary Key
    reader = unicode_csv_reader(extract_properties['uploaded_file'],dialect='pipes') #CSVfunction  
    for idx, row in enumerate(reader):
        if idx <= (extract_properties['header_row_num'])+3: #Header is not always 1st row of file
            pass
        else:
            try:
                obj, created = MastTable.objects.create( #I was originally using 'get_or_create'
                    evidence=evidence_obj,
                    var2=row[0],
                    var3=row[1],
                    var4=row[2],
                    var5=row[3],
                    var6=date_convert(row[4],row[5]), #funct using 'dateutil.parser.parse'
                    var7=date_convert(row[6],row[7]),
                    var8=date_convert(row[8],row[9]),
                    var9=date_convert(row[10],row[11]),
                    var10=date_convert(row[12],row[13]),
                    var11=date_convert(row[14],row[15]),
                    var12=date_convert(row[16],row[17]),
                    var13=date_convert(row[18],row[19]),
                    var14=row[20],
                    var15=row[21],
                    var16=row[22],
                    var17=row[23],
                    var18=row[24],
                    var19=row[25],
                    var20=row[26],
                    var21=row[27],
                    var22=row[28],
                    var23=date_convert(row[29],row[30]),
                    var24=date_convert(row[31],row[32]),
                    var25=date_convert(row[33],row[34]),
                    var26=date_convert(row[35],row[36]),)
            except Exception as e:  #This logs any exceptions to a custom DB table
                print "Error",e
                print "row",row
                print "idx:",idx
                SystemExceptionLog.objects.get_or_create(indexrow=idx, errormsg=e.args[0],     
                timestamp=datetime.datetime.now(),   
                uploadedfile=extract_properties['uploaded_file'])
                continue
    return True 

Django中最基本、最有效的优化是减少对数据库的查询数量。这对于100个查询是正确的,对于50万个查询也是正确的

您不应该使用
mastable.objects.create()
,而应该构建一个未保存模型实例的列表,并使用
mastable.objects.bulk\u create(模型列表)
在尽可能少的往返数据库中创建它们。这应该会大大加快速度

如果您使用的是MySQL,您可以增加
max\u allowed\u packet
设置以允许更大的批处理。它的1MB默认值相当低。PostGRESQL没有硬编码限制。如果您仍然遇到性能问题,可以切换到。创建500.000个python对象可能会有点开销。在我最近的一次测试中,使用
connection.cursor
执行完全相同的查询的速度大约快了20%


最好将文件的实际处理留给后台处理,例如使用芹菜,或使用
StreamingHttpResponse
在处理过程中提供反馈

此csv文件是否包含无效行?我是说你真的需要这条线吗

except Exception as e:  #This logs any exceptions to a custom DB table
如果没有引发此类错误,则应使用
bulk\u create()
,而不仅仅是
create()

我还建议在单个事务中执行导入。它是一个巨大的增速器:

from django.db import transaction

with transaction.atomic():
    processor_table(extract_properties)

异常报告是因为源数据可以是动态的。之前,我对时髦的编解码器有一些问题。我尝试过使用批量创建。我有点不确定,但对“transaction.atomic()”感兴趣。这类似于只使用MySQL接口和跳过Django ORM吗?(对我来说,这是一个考虑过的替代方案)跳过Django ORM和使用事务不是替代方案-您可以(而且,imho,应该)同时做这两件事。首先尝试
transaction.atomic()
,它很简单,可以将应用程序的速度提高一个数量级。之后,切换到纯SQL以获得额外的速度提升。
from django.db import transaction

with transaction.atomic():
    processor_table(extract_properties)