Python脚本执行AD用户数据SQL导入时触发KeyError: 0错误
Python脚本执行AD用户数据SQL导入时触发KeyError: 0错误
看起来你遇到的这个KeyError: 0问题很典型——根源出在你对解析后的数据类型理解错了。
问题原因分析
你用json.loads()解析PowerShell返回的输出后,ad_users_list里的每一个row其实是Python字典对象(键值对形式,键就是你在PowerShell里定义的那些字段名,比如Enabled、givenName),但你在cursor.execute()里却用row[0]、row[1]这种数字索引去取值——字典根本不认识数字键,自然就抛出KeyError了。
解决方案
有几种简单的修改方式,核心就是用字典的键来取值,或者把字典转换成和SQL列顺序匹配的有序值列表:
方式1:直接通过字典键逐个取值(最直观)
修改插入循环的代码,把数字索引换成对应的字段键名,确保顺序和SQL插入的列完全一致:
for row in ad_users_list: cursor.execute("INSERT INTO dbo.testpyimport (Enabled,givenName,sn,displayName,description,physicalDeliveryOfficeName,telephoneNumber,mail,streetAddress,l,st,postalCode,co,sAMAccountName,mobile,facsimileTelephoneNumber,ipPhone,title,department,manager,company,distinguishedname) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", row['Enabled'], row['givenName'], row['sn'], row['displayName'], row['description'], row['physicalDeliveryOfficeName'], row['telephoneNumber'], row['mail'], row['streetAddress'], row['l'], row['st'], row['postalCode'], row['co'], row['sAMAccountName'], row['mobile'], row['facsimileTelephoneNumber'], row['ipPhone'], row['title'], row['department'], row['manager'], row['company'], row['distinguishedname'])
方式2:用列表推导式按顺序提取值(更简洁,易维护)
先定义一个和SQL列顺序完全匹配的键列表,再批量提取值,这样后续如果字段顺序调整,只需要修改这个列表即可:
# 定义和SQL插入列顺序一致的字段键列表 column_keys = [ 'Enabled', 'givenName', 'sn', 'displayName', 'description', 'physicalDeliveryOfficeName', 'telephoneNumber', 'mail', 'streetAddress', 'l', 'st', 'postalCode', 'co', 'sAMAccountName', 'mobile', 'facsimileTelephoneNumber', 'ipPhone', 'title', 'department', 'manager', 'company', 'distinguishedname' ] for row in ad_users_list: # 按顺序提取每个字段的值 values = [row[key] for key in column_keys] cursor.execute("INSERT INTO dbo.testpyimport (Enabled,givenName,sn,displayName,description,physicalDeliveryOfficeName,telephoneNumber,mail,streetAddress,l,st,postalCode,co,sAMAccountName,mobile,facsimileTelephoneNumber,ipPhone,title,department,manager,company,distinguishedname) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", *values)
方式3:直接使用字典的values()(最简洁,但要注意顺序)
因为Python 3.7+的字典会保留插入顺序,而你在PowerShell里定义的PSCustomObject字段顺序和SQL列顺序完全一致,所以可以直接用row.values()来获取所有值,再用解包运算符*传入:
for row in ad_users_list: cursor.execute("INSERT INTO dbo.testpyimport (Enabled,givenName,sn,displayName,description,physicalDeliveryOfficeName,telephoneNumber,mail,streetAddress,l,st,postalCode,co,sAMAccountName,mobile,facsimileTelephoneNumber,ipPhone,title,department,manager,company,distinguishedname) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", *row.values())
额外注意事项
- 如果你担心AD里某些字段为空(比如
mobile可能没有值),可以在取值时设置默认值,比如row.get('mobile', '')或者row.get('mobile', None),避免出现键不存在的情况。 - 建议在批量插入前先测试单条数据:比如打印
ad_users_list[0]和对应的values,确认数据格式和顺序都正确,再执行全量插入。
备注:内容来源于stack exchange,提问作者John FNG
相关产品推荐
相关产品推荐

