Вставка нескольких записей с использованием executemany в pyodbc - PullRequest
0 голосов
/ 07 мая 2020

Я хочу знать, что влияет на скорость выполнения транзакции при использовании pyodb c. Я провожу инвентаризацию на конец месяца и написал сценарий, который загружает данные, сохраненные в шаблоне Excel, в SQL базу данных.

Вот мой код:

from tkinter import *
from tkinter import filedialog
import pyodbc  # Importing for storing in a DB
from tkinter import messagebox
import getpass
import os
import shutil
#import tktable
from datetime import datetime

import openpyxl
from openpyxl import load_workbook

master = Tk()

v = IntVar()

strForDB = os.getcwd() + '\DBINFO.txt'
openDBFile = open(strForDB, 'r')
currentDirForDB = openDBFile.read()
dbPath = currentDirForDB
openDBFile.close()


def uploadFile():
    print(v.get())

    if v.get()==1 or v.get()==2:
        fileName=filedialog.askopenfilename()
        print(fileName)

        #if v.get()==2:
        ############################## Setting up excel
        try:
            openWB = load_workbook(fileName)
        except:
            messagebox.showerror("Upload Error","Unable to open file")
            return

        sheetNameIn=openWB["In"]
        sheetNameOut=openWB["Out"]
        rowVal=2
        rowValOut=2
        cellValue=sheetNameIn.cell(row=rowVal,column=1).value
        cellValueOut=sheetNameOut.cell(row=rowValOut,column=1).value
        uniqueListOfInBarcodes=[]
        listOfInLocation=[]
        listOfOutBarcodes=[]

        firstLocation = sheetNameIn.cell(row=2, column=2).value
        if firstLocation == None or firstLocation == "":
            messagebox.showerror("Location Error", "First barcode needs to have a location. No location found")
            openWB.close()
            return
#################################### Getting a list of all items scanned out

        while cellValueOut!="" and cellValueOut!=None:
            listOfOutBarcodes.append(cellValueOut)
            rowValOut=rowValOut+1
            cellValueOut = sheetNameOut.cell(row=rowValOut, column=1).value



#################################### Getting a list of all items scanned in excluding the ones scanned out
        while cellValue!="" and cellValue!=None:
            #print(cellValue)
            locationValue=sheetNameIn.cell(row=rowVal,column=2).value
            if cellValue not in uniqueListOfInBarcodes and cellValue not in listOfOutBarcodes:
                uniqueListOfInBarcodes.append(cellValue)

                if locationValue==None or locationValue=="":
                    listOfInLocation.append(listOfInLocation[-1])
                else:
                    listOfInLocation.append(locationValue)

            rowVal=rowVal+1
            cellValue = sheetNameIn.cell(row=rowVal, column=1).value
        openWB.close()
        print(len(listOfInLocation))
        print(len(uniqueListOfInBarcodes))

        if len(listOfInLocation)!=len(uniqueListOfInBarcodes):
            messagebox.showerror("Location+Barcode Mismatch","Number of Locations do not match the number of barcodes entered.\nNo Entry made")
            return
        else:
            listForSubmission=[]

            for indexOfCode in range(len(uniqueListOfInBarcodes)):
                setForSubmission=(uniqueListOfInBarcodes[indexOfCode],listOfInLocation[indexOfCode],"WIP",datetime.now(),"","",getpass.getuser()+"-AutoUpload","","SITE","","","")
                '''
                ID Barcode Location Stage InTime OutTime PO InBy OutBy Site MovedBy OldLocations MovedAt
                '''
                listForSubmission.append(setForSubmission)

            deleteQueryLive="DELETE FROM AllTransactions2 WHERE Stage='WIP'"
            deleteQueryTest = "DELETE FROM AllTransactionsTest WHERE Stage='WIP'"

            submissionQueryTest="INSERT INTO AllTransactionsTest ([Barcode], [Location], [Stage], [InTime], [OutTime], [PO], [InBy], [OutBy], [Site], [MovedBy], [OldLocations], [MovedAt]) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
            submissionQueryLive="INSERT INTO AllTransactions2 ([Barcode], [Location], [Stage], [InTime], [OutTime], [PO], [InBy], [OutBy], [Site], [MovedBy], [OldLocations], [MovedAt]) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
            try:
                original = r'C:\LastMonthFile.csv'
                target = r'Z:\MonthEndBackup\LastMonthFile.csv'
                shutil.copyfile(original, target)
            except:
                messagebox.showerror("Backup Error","Unable to backup the database, no upload made")
                return

            con=pyodbc.connect(dbPath)
            cur=con.cursor()
            if v.get()==1:
                cur.execute(deleteQueryTest)
                con.commit()
                cur.executemany(submissionQueryTest,listForSubmission)

                con.commit()
                messagebox.showinfo("Success","Data has been uploaded.")
                master.destroy()
            elif v.get()==2:
                confirmation = messagebox.askyesno("Confirmation",
                                                   "Are you sure you want to update the LIVE DATABASE?\nOnce you click yes, you will not be able to undo any changes!")
                if confirmation==True:
                    cur.execute(deleteQueryLive)
                    con.commit()
                    cur.executemany(submissionQueryLive, listForSubmission)

                    con.commit()
                    messagebox.showinfo("Success", "Data has been uploaded.")
                    master.destroy()



frameForRadio=Frame(master)
frameForRadio.grid(row=0,column=0)
rad_Test=Radiobutton(frameForRadio, text="Test", variable=v, value=1)
rad_Test.grid(row=0,column=0)
rad_Live=Radiobutton(frameForRadio, text="Live", variable=v, value=2)
rad_Live.grid(row=1,column=0)
btn_upload=Button(frameForRadio,text="Upload",command=uploadFile).grid(row=2,column=0)
mainloop()

Когда Я запускаю файл в тестовой среде, все транзакции занимают около 10 минут. Однако, когда я работаю в реальной среде, транзакция занимает 3-4 часа. В файле Excel содержится около 4000-5000 записей, в тестовой базе данных - около 1000 записей, а в живой базе данных - 15000 записей. Имеет ли значение количество записей в базе данных такое существенное различие? количество записей.

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