We're dealing with an issue with the Identify task in a MapService not returning all visible fields (sounds like a bug; they show up in a query, but not via Identify). A coworker determined that reordering the fields for the layer in the Map within the project file fixes the issue. Note: we're reordering the fields as they appear in the map, not actually changing the structure of the data with a geoprocessing tool. Using the "Reset Field Order" option also seems to work.
So we have this workaround, but the only problem is we're dealing with quite a few layers for quite a few aprx files and I'd like to do this programmatically but it's not looking like ArcPy has any built-in method for accomplishing this.
Does one exist?
I'm really hoping I won't have to do this manually!
1 Answer 1
You can do this using the cim
object with arcpy. See the following code derived from Example 2. Note, you don't say how you're re-ordering the fields, so I'm just reversing the order. If you need more control over how you re-order, you'll need to build up some custom sort logic. I'll note it's a little more challenging than just sorting a list, or even a list of dicts, as each item seems to be an object of CIMFieldDescription
which you need to dive into. (Thus why I took the lazy way of just reversing the list instead of looking at field names)
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('YOUR MAP NAME')[0]
l = m.listLayers("YOUR LAYER NAME")[0]
cim = l.getDefinition('V2')
cim.featureTable.fieldDescriptions #These are the fields, in order.
>[<arcpy.cim.CIMVectorLayers.CIMFieldDescription object at 0x0000018A1B3D6408>, <arcpy.cim.CIMVectorLayers.CIMFieldDescription object at 0x0000018A1B3D64C8>, <arcpy.cim.CIMVectorLayers.CIMFieldDescription object at 0x0000018A1B3D6488>, <arcpy.cim.CIMVectorLayers.CIMFieldDescription object at 0x0000018A1B3D6508>, <arcpy.cim.CIMVectorLayers.CIMFieldDescription object at 0x0000018A1B3D6548>]
for f in cim.featureTable.fieldDescriptions: print(f.fieldName)
>OBJECTID
>Shape
>test
>field2
>field3
fd = cim.featureTable.fieldDescriptions #save these, this is what you'll modify
rev = [for f in reversed(cim.featureTable.fieldDescriptions)] #make a new, reversed list
for x in rev: print(x.fieldName)
>field3
>field2
>test
>Shape
>OBJECTID
cim.featureTable.fieldDescriptions = rev #overwrite the fieldDescriptions with the reversed list
l.setDefinition(cim) #persist the changes
-
Perfect! I've actually used the cim object before to do some other stuff, so I should have thought to look there. Thanks for the answer :)bgfield– bgfield2022年01月31日 16:17:48 +00:00Commented Jan 31, 2022 at 16:17