django-rest-framework 實現檔案批量匯入
阿新 • • 發佈:2018-12-21
最近做了一個讀取外部excel檔案內容並批量匯入到資料庫的功能:
使用的環境:python3.5 django-rest-framework
讀取excel檔案需要的包:xlrd
實現批量匯入使用的是:bulk_create方法,此方法可以一次性將資料匯入到資料庫,速度快,但是不能去重;
如果想要對資料去重,還有一個方法是get_or_create,但是匯入比較耗時;
程式碼如下:
class Resource_Distribution(ModelViewSet): serializer_class = Resource_DisSerializer pagination_class = PageNumberII() def batch(self, request, pk, *args, **kwargs): # 獲取前端傳過來的excel檔案 files = request.FILES.get('rest_file') file = files.file if not all(files): return Response({'info': 'error', 'code': 400}) if (request.user.perm_id == 2) \ or request.user.perm_id == 1 \ or (request.user.perm_id == 3): # 開啟excel檔案,並讀取去內容 ExcelFile = xlrd.open_workbook(filename=None, file_contents=file.read()) sheet = ExcelFile.sheet_by_index(0) total_rows = sheet.nrows head = sheet.row_values(0) emp_queryset = Employee.objects.filter(com_id=request.user.com_id) emp_dict = {} for emp in emp_queryset: emp_dict[emp.employee_number] = emp.employee_name col_list = [] row_list = [] num_list = [] for i in range(3, 8): col_list.append(sheet.col_values(i)[1:]) rest_list = col_list none_name = [] for list in rest_list: for number in list: if number not in emp_dict: none_name.append(number) if len(none_name) > 0: return Response({'info': 'repeat', 'code': 406, 'data': json.dumps(none_name)}) flo_obj = Floors.objects.filter(department_id=request.user.department_id).all() eqt_obj = Equipment.objects.filter(department_id=request.user.department_id).all() ori_obj = Orientations.objects.filter(case_id=int(pk)).all() floor_dict = {} eqt_dict = {} ori_dict = {} None_floor = [] None_ori = [] None_eqt = [] for obj in flo_obj: floor_dict[obj.floor] = obj.id result = check_exist(sheet, 0, 9, floor_dict, None_floor) if result['code'] == 400: return Response(result) for obj in eqt_obj: eqt_dict[obj.equipment_name] = obj.id result = check_exist(sheet, 2, 1, dict, None_eqt) if result['code'] == 400: return Response(result) for obj in ori_obj: ori_dict[obj.orientation] = obj.id result = check_exist(sheet, 1, 13, ori_dict, None_ori) if result['code'] == 400: return Response(result) for v in range(1, total_rows): row_list.append(sheet.row_values(v)[::]) for v in row_list: num_list.append(v) # 定義一個空列表儲存excel檔案內容 datalist = [] if head[0] == '樓層' and head[1] == '夾位' and head[2] == '裝置編號' and head[3] == '生產負責人' and head[ 4] == '生技負責人' and head[5] == '制工負責人' and head[6] == '品管負責人' and head[7] == '維修負責人': dr = False try: for n in num_list: datalist.append(models.Resource_distribution(floor_id=int(n[0]), orientation_id=int(n[1]), equipment_id=int(n[2]), production_number=n[3], production=emp_dict[n[3]], technology_number=n[4], technology=emp_dict[n[4]], manufacture_number=n[5], manufacture=emp_dict[n[5]], QC_number=n[6], QC=emp_dict[n[6]], maintain_number=n[7], maintain=emp_dict[n[7]], )) # 使用bulk_create方法進行批量匯入 models.Resource_distribution.objects.bulk_create(datalist) dr = True except: pass if dr == False: return raise_repeat() else: return raise_success() else: return raise_error() else: return raise_error()