更高效地从 qtableWidget 更新和插入 MYSQL 数据库

Posted

技术标签:

【中文标题】更高效地从 qtableWidget 更新和插入 MYSQL 数据库【英文标题】:Update and insert from qtableWidget into MYSQL database more efficiently 【发布时间】:2021-12-29 09:29:02 【问题描述】:

我正在使用 PyQt5 构建一个桌面应用程序,用于连接、加载数据、将数据插入和更新 mysql 数据库。我想出更新数据库并将数据插入数据库的方法。但我觉得在计算速度方面应该有一种更快的方法来做到这一点。如果有人可以提供帮助,那将非常有帮助。我现在更新数据库的就是这个-

def log_change(self, item):
        self.changed_items.append([item.row(),item.column()])
        
        # I connect this function to the item changed signal to log any cells which have been changed 


def update_db(self):
        
        # Creating an empty list to remove the duplicated cells from the initial list
        
        self.changed_items_load= []
        [self.changed_items_load.append(x) for x in self.changed_items if x not in self.changed_items_load]
        
        # loop through the changed_items list and remove cells with no values in them
        
        for db_wa in self.changed_items_load:
            if self.tableWidget.item(db_wa[0],db_wa[1]).text() == "":
                self.changed_items_load.remove(db_wa)
        
        try:
            
            mycursor = mydb.cursor()
            
            # loop through the list and update the database cell by cell
            
            for ecr in self.changed_items_load:
                    
                    command = ("update table1 set `col_name` = %s where id=%s;")
                    
                    # table widget column name matches db table column name
                    
                    data = (str(self.tableWidget.item(ecr[0],ecr[1]).text()),int(self.tableWidget.item(ecr[0],0).text()))
                    
                    mycursor.execute(command.format(col_name = self.col_names[ecr[1]]),data)
                
                    # self.col_names is a list of the tableWidget columns 
                    
            mydb.commit()        
            mycursor.close()
            
        except OperationalError:
            Msgbox = QMessageBox()
            Msgbox.setText("Error! Connection to database lost!")
            Msgbox.exec()
        
        except NameError:
            Msgbox = QMessageBox()
            Msgbox.setText("Error! Connect to database!")
            Msgbox.exec()
            

为了将数据和新行插入数据库,我可以在网上找到一些相关信息。但是我无法一次插入多行,也无法为每行插入不同的列长度。就像我只想在第 1 行插入 2 列,然后在第 2 行插入 3 列......类似的东西。

def insert_db(self):
        
        # creating a list of each column
        
        self.a = [self.tableWidget.item(row,1).text() for row in range (self.tableWidget.rowCount()) if self.tableWidget.item(row,1) != None]
        self.b = [self.tableWidget.item(row,2).text() for row in range (self.tableWidget.rowCount()) if self.tableWidget.item(row,2) != None]
        self.c =  [self.tableWidget.item(row,3).text() for row in range (self.tableWidget.rowCount()) if self.tableWidget.item(row,3) != None]
        self.d =  [self.tableWidget.item(row,4).text() for row in range (self.tableWidget.rowCount()) if self.tableWidget.item(row,4) != None]
        
        
        try:
            
            mycursor = mydb.cursor()
            
            mycursor.execute("INSERT INTO table1(Name, Date, Quantity, Comments) VALUES ('%s', '%s', '%s', '%s')" %(''.join(self.a),
                                                                ''.join(self.b),
                                                                ''.join(self.c),
                                                                ''.join(self.d)))
                
                
                    
            mydb.commit()        
            mycursor.close()
            
        except OperationalError:
            Msgbox = QMessageBox()
            Msgbox.setText("Error! Connection to database lost!")
            Msgbox.exec()
        
        except NameError:
            Msgbox = QMessageBox()
            Msgbox.setText("Error! Connect to database!")
            Msgbox.exec()

我们将不胜感激。谢谢。

【问题讨论】:

您只能每 xxx 行提交一次。例如,从循环中删除提交,在循环中添加一个计数器并仅每 500 个查询提交一次,当然在循环完成后提交。查询并不耗费时间,但事务却是。因此,如果您进行较少的交易,您的速度将显着提高 提交语句不在循环中。 可以进行多个查询,但语法取决于您使用的 sql 引擎。要更新现有记录,请使用 UPDATE 语句。也就是说,考虑使用 QtSql 模块并在QTableView 上设置QSqlTableModel。 【参考方案1】:

如果我只想在第 1 行插入 2 列,然后在第 2 行插入 3 列

没有。给定的数据库表具有特定数量的列。这是“表”定义中不可分割的一部分。

INSERT 将新行添加到表中。可以构造一个“一次”插入多行的单个 SQL 语句。

UPDATE 修改表的一行或多行。这些行由 Update 语句中指定的某些条件指示。

%s 构造SQL 是有风险的——如果插入的字符串中有引号,就会有麻烦。

(我希望这些 cmets 可以帮助您进入理解数据库的下一阶段。)

【讨论】:

以上是关于更高效地从 qtableWidget 更新和插入 MYSQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

QTableWidget滚动与选定的项目

Qt下QTableWidget的使用

在 qTableWidget 单元格中选择文本

MySQL 性能:嵌套插入/重复键与多次更新

在 QtableWidget 中插入多项

如何高效地从多个表中查询子记录?