我正在尝试将一个非常大的.csv
文件从Django的upload form
保存到MongoDB
中,它可以工作,但它需要太多的时间来处理,所以我决定使用多处理,这种方法缩短了一点时间,但是CPU内核达到了100%,所以我想让我的代码更低一点计算成本。以下是我的代码
views.py
def save_to_db(line): # I think this part cost the most time
column = line.split(",")
kokyaku.objects.create(顧客CD = int(column[0]), 顧客補助CD = int(column[1]),
顧客名称s=str(column[2]), 顧客名称=str(column[3]),
顧客名称カナ=str(column[4]), 法人名称=str(column[5]),
代表者名称=str(column[6]),住所=str(column[7]),
電話番号=str(int(column[8])),地区名称=str(column[9]),
データマッチ用電話番号=int(column[10]),契約状態=str(column[11])
)
def upload(request):
data = {}
if "GET" == request.method:
return render(request, "main/upload.html", data)
# if not GET, then proceed
csv_file = request.FILES["csv_file"]
file_type = request.POST.get("type", "")
if not csv_file.name.endswith('.csv'):
messages.error(request,'File is not CSV type')
return HttpResponseRedirect(reverse("upload"))
file_data = csv_file.read().decode("utf-8")
lines = file_data.split("\n")
if file_type == "val3":
with concurrent.futures.ProcessPoolExecutor() as executor:
executor.map(save_to_db, lines)
return HttpResponseRedirect(reverse("upload"))
顺便说一句。这是我来自models.py
的类,如果它也有帮助的话
class kokyaku(models.Model):
顧客CD = models.IntegerField(blank=True)
顧客補助CD = models.IntegerField(blank=True)
顧客名称s = models.TextField(blank=True)
顧客名称 = models.TextField(blank=True)
顧客名称カナ = models.TextField(blank=True)
法人名称 = models.CharField(max_length=15, blank=True)
代表者名称 = models.CharField(max_length=15, blank=True)
住所 = models.TextField(blank=True)
地区名称 = models.TextField(blank=True)
電話番号 = models.IntegerField(blank=True)
データマッチ用電話番号 = models.IntegerField(blank=True)
契約状態 = models.CharField(max_length=2, blank=True)
def __str__(self):
string = str(self.顧客CD) + " - " + self.顧客名称
return string
发布于 2019-12-25 10:16:09
您可以尝试使用bulk_create
,但我不确定这是否适用于MongoDB。
def save_to_db(line):
column = line.split(",")
return kokyaku(col0 = column[0], col1 = column[1], ... )
def upload(request):
...
lines = file_data.split("\n")
kokyaku.objects.bulk_create(map(save_to_db, lines))
return HttpResponseRedirect(reverse("upload"))
更新
下面是使用try/catch块的另一个解决方案:
def upload(request):
...
lines = file_data.split("\n")
items = []
for line in lines:
column = line.split(',')
try:
item = kokyaku(col0 = int(column[0]), ...)
items.append(item)
except ValueError:
print(item)
kokyaku.objects.bulk_create(items)
https://stackoverflow.com/questions/59474638
复制相似问题