MySQL插入报1064(42000)语法错误,批量插入失败求助
问题解决:批量插入MySQL时的语法错误
错误原因分析
你遇到的1064 (42000)语法错误,核心原因有两个:
- 空列表导致无效SQL:当
files_list为空时,生成的SQL会变成INSERT INTO blocks_files (order_id, op_id, file_id, imgs) VALUES ;,VALUES后无内容直接中断,触发near ''的报错。 - 字符串拼接的语法与安全风险:直接用
map(str, files_list)拼接SQL语句,不仅会引入SQL注入风险,还可能因字段值包含特殊字符(如引号)破坏语法;另外你提到表的列是file,但代码中SQL写的是file_id,如果这不是笔误,会导致「列不存在」的额外错误。
修复方案
使用MySQL支持的参数化批量插入,同时处理空列表的情况,既避免语法错误,又保证安全性:
修复后的代码
def blocks_files(self, db, order_id, op_id, file_ids, images): """Filling the blocks_files table.""" files_list = [] for file in file_ids: if file in images: # 根据需求选择:要么转成逗号分隔字符串,要么保留列表格式 imgs_str = ",".join(map(str, images[file])) # 若需保留原列表字符串格式,替换为:imgs_str = str(images[file]) files_list.append((order_id, op_id, file, imgs_str)) # 无数据时直接返回,避免生成无效SQL if not files_list: logging.debug("No data to insert into blocks_files.") return try: logging.debug("Inserting data in blocks_files.") cursor = db.cursor() # 注意:如果表列是`file`而非`file_id`,请修正下面的列名 placeholders = ", ".join(["(%s, %s, %s, %s)"] * len(files_list)) query = f""" INSERT INTO {self.FILES_TABLE} (order_id, op_id, file, imgs) VALUES {placeholders} """ # 将二维列表展平为一维参数元组 flat_values = tuple(item for sublist in files_list for item in sublist) cursor.execute(query, flat_values) db.commit() cursor.close() logging.debug("Data inserted successfully!") except connector.Error as err: logging.error(err) db.rollback() # 出错时回滚事务
关键修改点
- 空列表校验:先判断
files_list是否为空,直接跳过插入逻辑,避免生成无效SQL。 - 参数化查询:用
%s占位符代替字符串拼接,让MySQL驱动自动处理参数转义,彻底避免SQL注入和语法错误。 - 列名修正:根据你描述的表结构,将SQL中的
file_id改为file(如果表列确实是file)。 - 事务回滚:出错时添加
db.rollback(),防止事务挂起导致后续操作异常。 - 代码优化:用
file in images替代images.__contains__(file),更符合Python编码习惯。
内容的提问来源于stack exchange,提问作者SomeRandomDude111
相关产品推荐
相关产品推荐

