Why would cim_lyr.featureTable.fieldDescriptions return an empty list when the feature layer clearly contains fields? @JeffBarrette @JeffMoulds
Solved! Go to Solution.
I want to thank you Marvis for sending me your data. I was able to reproduce and then checked in with our CIM experts. I learned something too.
"We only write field descriptions if they differ from the default for that field. Once you make some change (to the field visibility, or alias, or formatting, etc.) to any field, then we populate that entire collection. Doing it this way keeps the layer representation small. Think of them as overrides."
So to get this to work, I simply went into the fields view and changed the visibility of OID. I made it not visible. Then I saved the project and ran the same code and I could see ALL fields.
Jeff - arcpy.mp and Layout teams
Marvis,
It shouldn't. Can you supply the few lines of code that grabs the field list?
Jeff - arcpy.mp and Layout teams
p=arcpy.mp.ArcGISProject("current")
m=p.listMaps()[0]
l=m.listLayers()[0]
c=l.getDefinition('V2')
fields=c.featureTable.fieldDescriptions
print (fields) prints an empty list.
According to property tip in the image above, there is an expectation for an argument for the fieldDescriptions property otherwise it creates an empty list.
I'm not sure what to say. Does your FC have an attribute table? I just tried the following on a simple polygon layer.
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps()[0]
l = m.listLayers()[0]
c = l.getDefinition('V2')
fields = c.featureTable.fieldDescriptions
len(fields)
15
You are welcome to send me a layer package to jbarrette@esri.com and I can take a look.
Jeff - arcpy.mp and Layout teams
I want to thank you Marvis for sending me your data. I was able to reproduce and then checked in with our CIM experts. I learned something too.
"We only write field descriptions if they differ from the default for that field. Once you make some change (to the field visibility, or alias, or formatting, etc.) to any field, then we populate that entire collection. Doing it this way keeps the layer representation small. Think of them as overrides."
So to get this to work, I simply went into the fields view and changed the visibility of OID. I made it not visible. Then I saved the project and ran the same code and I could see ALL fields.
Jeff - arcpy.mp and Layout teams
Jeff, I used your methodology and was able to get the fields to become available so I will mark it as the answer. However, this methodology is not very practical for scripting purposes. Attempting to access the fields inside a python script will always return an empty list unless the user first manually updates a field which then makes the script unnecessary.
Fyi: My original goal was to run a script that would freeze certain fields of a given attribute table. Jeff had mentioned that this could be accomplished by the isLocked property on the cim.
I understand the catch-22. The CIM was designed to be an efficient storage mechanism for quickly recreating the content in a project. The CIM was not designed specifically to support APIs but rather can be used by APIs to access properties that may not be available to the published API. This "known limitation" means that we need to add field management capabilities to the published API. That will take time and in some cases, may not happen.
Jeff - arcpy.mp and Layout Teams
I am in the same boat here. I have a script that adds a feature class multiple times with different definition queries and there are MANY fields in them. I created a bit of a workaround to "enable" the CIM fieldDescriptions and that is to use an arcpy.AlterField to update the SHAPE field's alias:
arcpy.AlterField_management(lyr, "SHAPE", new_field_alias="Shape")
I wish this wasn't the case as it add a lot of time on the running of the script.
I just found out that if the layer's datasource is the same in the same map, it will "enable" the CIM fieldDescriptions for all of them. Just add a check if you have already altered the field for a datasource or if the length of the fieldDescriptions is 0.