使用Python向MySQL数据库插入NULL值失败的问题排查
问题:插入MySQL时无法生成真实NULL值,报错
1054 (42S22): Unknown column 'None' in 'field list' 问题详情
以下是报错的代码片段:
def blocks_files(self, db, order_id, op_id, file_ids, images): """Creating record in blocks_files table.""" files_list = [] keys = list(images.keys()) for file in file_ids: if str(file) in keys: new = str() for i in range(len(images[str(file)])): new += '%s, ' % str((images[str(file)])[i]) files_list.append((order_id, op_id, file, new)) else: files_list.append((order_id, op_id, file, None)) try: logging.debug( "Inserting data in blocks_files table." ) cursor = db.cursor() query = ( f"INSERT INTO {self.FILES_TABLE}" f"(order_id, op_id, file_id, imgs)" f"VALUES {(', '.join(map(str, files_list)))};" ) cursor.execute(query) db.commit() cursor.close() logging.debug( "Data inserted successfully!" ) except connector.Error as err: logging.error(err)
问题出在files_list.append((order_id, op_id, file, None))这行:原本期望给imgs字段插入MySQL的真实NULL值,但日志报错提示找不到名为None的列。需要明确:MySQL的真实NULL显示为无引号的黑色文本,而字符串"NULL"是带引号的灰色文本,二者完全不同。
错误原因
当前代码通过手动拼接字符串生成SQL语句,map(str, files_list)会把Python的None转换成字符串"None",最终生成的SQL会把None当成列名而非NULL值,导致数据库报错。同时这种字符串拼接方式还存在SQL注入风险。
解决方案:使用参数化查询
直接使用MySQL连接器支持的参数化查询,Python的None会被自动转换为MySQL的真实NULL值,同时避免SQL注入问题。修改后的代码如下:
def blocks_files(self, db, order_id, op_id, file_ids, images): """Creating record in blocks_files table.""" files_list = [] keys = list(images.keys()) for file in file_ids: if str(file) in keys: # 优化图片字符串拼接,避免末尾多余逗号 img_str = ', '.join(str(img) for img in images[str(file)]) files_list.append((order_id, op_id, file, img_str)) else: files_list.append((order_id, op_id, file, None)) try: logging.debug("Inserting data in blocks_files table.") cursor = db.cursor() # 使用参数化占位符,避免手动拼接SQL query = ( f"INSERT INTO {self.FILES_TABLE} (order_id, op_id, file_id, imgs) " "VALUES (%s, %s, %s, %s)" ) # 批量插入多条数据 cursor.executemany(query, files_list) db.commit() cursor.close() logging.debug("Data inserted successfully!") except connector.Error as err: logging.error(err)
关键修改点:
- 用
%s作为参数占位符(适配mysql-connector-python),Python的None会被自动映射为MySQL的NULL - 使用
executemany批量插入数据,比单条插入更高效,同时彻底避免手动拼接VALUES的错误 - 优化了图片字符串的生成逻辑,用
','.join替代循环拼接,解决原代码中末尾多余逗号的问题
内容的提问来源于stack exchange,提问作者SomeRandomDude111
相关产品推荐
相关产品推荐

