`cursor.execute()`和`cursor.executemany()`在向数据库插入数据时具有不同的功能和用途,它们的主要区别在于**执行效率、插入方式以及参数要求**等方面。具体分析如下:
1. **执行效率**
- **`execute()`**:通过循环调用`execute()`方法插入多条数据通常效率较低,因为每次循环都会与数据库进行一次交互。
- **`executemany()`**:使用`executemany()`可以实现单次数据库交互中插入多条记录,从而显著提高大量数据传输的效率。
2. **插入方式**
- **`execute()`**:每次调用可以执行插入单条数据的操作。如果要插入多条数据,需要对每一条数据单独调用`execute()`方法。
- **`executemany()`**:此方法接受一个包含多个数据元的列表或元组,允许在一次函数调用中插入多条数据。
3. **参数要求**
- **`execute()`**:可以接受已经格式化好的SQL语句,直接执行该语句。
- **`executemany()`**:需要提供一个含有占位符%s的SQL语句模板和一组数据。该方法将数据与占位符自动匹配并插入到数据库中。
4. **适用场景**
- **`execute()`**:更适合少量数据的插入或当数据格式不同时需要特殊处理的情况。
- **`executemany()`**:当需要批量插入大量相同结构的数据时,此方法更加高效。
5. **错误处理**
- **`execute()`**:每次调用出错时,仅影响当前处理的数据条目,便于错误定位和数据校验。
- **`executemany()`**:若出现错误可能会影响整个批次的数据提交,但通常提供更详细的错误信息来帮助调试。
6. **灵活性**
- **`execute()`**:由于可以构造任意SQL语句执行,提供了更多的编程灵活性。
- **`executemany()`**:在操作上相对简单直接,但在某些特定情况下可能缺乏灵活性。
7. **易用性**
- **`execute()`**:对于不熟悉占位符和参数化查询的用户来说,可能需要更多的学习和实践。
- **`executemany()`**:由于其批量处理的特性,对于大批量数据处理非常方便且直观。
8. **性能对比**
- **`execute()`**:在处理小批量数据时性能尚可接受,但随着数据量的增长,性能会显著下降。
- **`executemany()`**:在大量数据插入时表现出色,特别是在与原生SQL语句相比,优化了字符串拼接上的开销。
针对上述分析,可以考虑以下几点建议:
- 当处理的数据量较小或者各数据项差异较大时,使用`execute()`可能更为合适。
- 如果遇到大量数据需要批量插入,应优先考虑使用`executemany()`来提高效率。
- 对于新手而言,开始时可以多使用`execute()`以熟悉各种SQL语句和处理过程。
- 性能测试是判断哪种方法更适合当前需求的有效手段,可以在具体应用场景下进行试验。
总的来说,`cursor.execute()`和`cursor.executemany()`各有优势,在不同的使用场景中发挥不同的作用。了解它们的这些关键区别之后,可以根据实际需求和条件选择最合适的数据插入方法。
def batch_update(updates, db_file, table_name):
with db_lock:
try:
with sqlite3.connect(db_file) as conn:
cursor = conn.cursor()
# 开始事务
conn.execute('BEGIN TRANSACTION')
for update in updates:
# logging.info(f"{update}")
try:
iccid, update_statement, values = update
values = eval(values) # 将字符串转换为元组
# 预编译更新SQL语句
update_query = "UPDATE {} SET {} WHERE ICCID = ?".format(table_name, update_statement)
values += (iccid,) # 将ICCID添加到参数值中
cursor.execute(update_query, values)
print(f"{iccid}-成功更新行数据-{values}")
# logging.info(f"{iccid}-成功更新行数据-{values}")
except Exception as e:
print(f"update:{e}")
logging.info(f"update:{e}")
continue
# 提交事务
conn.execute('COMMIT')
except sqlite3.Error as e:
print(f"更新行数据时出现错误: {e}")
logging.error(f"更新行数据时出现错误: {e}")
def batch_update(updates, db_file, table_name):
with db_lock:
try:
with sqlite3.connect(db_file) as conn:
conn.execute("PRAGMA synchronous=OFF") #关闭同步
conn.execute("BEGIN TRANSACTION") #显式开启事务
cursor = conn.cursor()
# update_queries = []
update_values = []
for update in updates:
# print(f"update:{update}")
iccid, update_statement, values = update
values = eval(values) # 将字符串转换为元组
print(f"当前{values}-正在更新")
# update_queries.append(update_query)
update_values.append(values + (iccid,))
# print(f"update_queries:{update_queries}")
# print(f"update_values:{update_values}")
update_query = "UPDATE {} SET {} WHERE ICCID=?".format(table_name, update_statement)
# print(f"update_query:{update_query}")
# 一次性执行多个更新操作
cursor.executemany(update_query, update_values)
print(f"成功更新行数据")
conn.execute('COMMIT') # 提交事务
except Exception as e:
print(f"更新行数据时出现错误: {e}")
logger.error(f"更新行数据时出现错误: {e}")
def process_iccid(i, iccid, table_name):
update_statement = 'status=?, Message=?, tet=? ,result=? ,查询时间=?'
values = (str(status[0]), message[0], f"-", f"-", nowtime)
return i, iccid,update_statement,values