使用多游标将表字段值导入要素类:脚本无报错但数据未写入
问题排查与修复方案
为啥脚本没生效?
- 游标遍历一次就“罢工”:你嵌套了两个游标,第一次遍历要素类的行时,
SearchCursor会把CSV里的所有数据读完,后面再遍历要素类的其他行,source_cursor已经没数据了,自然匹配不到更新。 - 更新时机错了:你每给一个字段赋值就调用一次
updateRow,这不仅多余,还可能导致字段没更完就提前保存,虽然这里不是主要问题,但也是不合理的写法。 - 路径可能写错了:你写的
r'C:DATA\valueTable.csv'少了盘符后面的反斜杠,应该是r'C:\DATA\valueTable.csv',虽然脚本没报错,但说不定根本没读到CSV的数据。 - 没处理选中行:你说要更新选中行,但当前脚本会遍历要素类所有行,没限定只改选中的。
修复后的脚本
先把CSV的数据存进字典(用连接字段当索引),再遍历要素类匹配更新,既快又不会出现游标失效的问题:
import arcpy arcpy.env.overwriteOutput = True # 字段列表(源和目标的字段顺序要对应上) join_field = "JoinField" fields = [join_field, "field1", "field2", "fieldn"] # 修正路径(注意盘符后面的反斜杠) featureclass = r'C:\DATA\name.gdb\featureclass' table = r'C:\DATA\valueTable.csv' # 先把CSV里的数据全读到字典里,用连接字段值当键,找起来快 source_data = {} with arcpy.da.SearchCursor(table, fields) as source_cursor: for row in source_cursor: source_data[row[0]] = row # 如果要只更新选中行,先获取选中行的OID,构建过滤条件 oid_field = arcpy.Describe(featureclass).OIDFieldName selected_oids = [] # 获取选中行的OID列表 with arcpy.da.SearchCursor(featureclass, [oid_field], where_clause="OBJECTID IN (SELECT OBJECTID FROM " + featureclass + "_Selection)") as sel_cursor: selected_oids = [row[0] for row in sel_cursor] # 构建只处理选中行的条件,如果没选中就处理所有行 where_clause = f"{oid_field} IN ({','.join(map(str, selected_oids))})" if selected_oids else "" # 遍历要素类进行更新 with arcpy.da.UpdateCursor(featureclass, fields, where_clause) as update_cursor: for update_row in update_cursor: current_join_value = update_row[0] # 如果当前行的连接字段在CSV数据里存在,就更新 if current_join_value in source_data: source_row = source_data[current_join_value] # 把CSV里的字段值逐个赋值过去 for idx in range(len(fields)): update_row[idx] = source_row[idx] # 所有字段都赋值完了,再更新这一行 update_cursor.updateRow(update_row)
几个关键改进
- 用字典存源数据:一次性把CSV数据读到内存里,不用反复遍历CSV,匹配速度快,还解决了嵌套游标遍历失效的问题。
- 统一更新行:等所有字段都改完再调用
updateRow,确保数据完整。 - 支持选中行更新:自动识别选中的要素,只更新这些行,符合你的需求。
- 修正路径:补全路径里的反斜杠,确保能正确读取CSV。
内容的提问来源于stack exchange,提问作者JohnD709
相关产品推荐
相关产品推荐

