I went through the documentation, and searched around but wasn't able to figure this out. What I want to do is export shapefiles, but have certain fields turn off. I was successful in turning off regular fields with delete.field.management, but I was unable to delete the FID
field, so now I am looking into turning the field off, instead of deleting it. Below is a part of the sample code I am working on before I fill in with my data -
fields= arcpy.ListFields(out_layer_file)
# Create a fieldinfo object
fieldinfo = arcpy.FieldInfo()
# Iterate through the fields and set them to fieldinfo
for field in fields:
if field.name == "FID":
fieldinfo.setVisible(field.name, "HIDDEN")
arcpy.MakeFeatureLayer_management(out_layer_file, "New2", field_info)
arcpy.SaveToLayerFile_management("New2", out_layer_file1, "ABSOLUTE")
Most of this was taken from ESRI, there isn't a lot of info on fieldinfo. I am new to python in general and trying to figure this out my error is this:
type 'exceptions.AttributeError': FieldInfo: Error in parsing arguments for SetVisible
Its not the FID field because even if I change it to a regular field I still get the error.
Any ideas - or any other documents on how to go about this?
-
2You say you want to export shapefiles? You haven't shown where you are exporting them. You're saving a layerfile, which is different to exporting a shapefile.Fezter– Fezter2017年02月26日 23:20:06 +00:00Commented Feb 26, 2017 at 23:20
-
For my current process I am turning the shapefile into a layer file in previous steps, turning the field off, and than back into a shapefile. From what I read field.info only works in read-only mode, so I didn't think it could work with a shapefile. The current process I have now is very long and tedious, but its the only thing I could think of.user92389– user923892017年02月26日 23:36:31 +00:00Commented Feb 26, 2017 at 23:36
-
1The first argument of setVisible is an integer, the index of the field to set not the name of the field to set.Michael Stimson– Michael Stimson2017年02月26日 23:36:43 +00:00Commented Feb 26, 2017 at 23:36
-
Use findFieldByName to get indexT. Wayne Whitley– T. Wayne Whitley2017年02月26日 23:38:54 +00:00Commented Feb 26, 2017 at 23:38
-
3FYI, layerfiles are not something you convert from shapefiles. They can point to shapefiles, and store symbology, layer settings, etc. But they are a proprietary format that can only be viewed by ArcGIS. You still need a shapefile (or some other spatial dataset) to open a layerfile.Fezter– Fezter2017年02月26日 23:40:21 +00:00Commented Feb 26, 2017 at 23:40
3 Answers 3
You should be getting the Field Info of an existing layer, not creating an empty Field Info object. Instead of using arcpy.FieldInfo()
, you need to use arcpy.Describe()
on your layer first, and then you can use the Layer property FieldInfo
.
desc = arcpy.Describe(out_layer_file)
field_info = desc.fieldInfo
# List of fields to hide
# desc.OIDFieldName is the name of the 'FID' field
fieldsToHide = [desc.OIDFieldName, 'OtherFieldOne', 'OtherFieldTwo']
for i in range(0, field_info.count):
if field_info.getFieldName(i) in fieldsToHide:
field_info.setVisible(i, "HIDDEN")
arcpy.MakeFeatureLayer_management(out_layer_file, "New2", "", "", field_info)
Also, in your MakeFeatureLayer()
line you were setting your field_info
however there were two more properties between the feature layer name and the field_info
property, so Make Feature Layer thought you were passing your field_info
as a where_clause. See Make Feature Layer help.
-
awesome, so that is where the " " come in to play. Very helpful, thank you - I have been stuck on this all day. And thank you everyone.user92389– user923892017年02月27日 01:38:00 +00:00Commented Feb 27, 2017 at 1:38
-
Do you know if
arcpy.Describe
is only way to return a FieldInfo object?fatih_dur– fatih_dur2019年03月27日 07:02:30 +00:00Commented Mar 27, 2019 at 7:02
Not sure if this code still works as I wrote it a good while back - at any rate, adapt and use at your own risk:
import arcpy
arcpy.env.overwriteOutput = True
arcpy.env.addOutputsToMap = False
mxd = arcpy.mapping.MapDocument(r'your path to target mxd')
df = arcpy.mapping.ListDataFrames(mxd, '*')[0]
LayerNeedsFieldsTurnedOff = arcpy.mapping.ListLayers(mxd, 'your target layer name', df)[0]
desiredFields = ['fieldname0', 'fieldname1', 'fieldname2', 'etc']
field_info = arcpy.Describe(LayerNeedsFieldsTurnedOff).fieldInfo
for i in range(field_info.count):
if field_info.getfieldname(i) not in desiredFields:
field_info.setvisible(i, 'HIDDEN')
arcpy.MakeFeatureLayer_management(LayerNeedsFieldsTurnedOff, 'temp_layer', '', '', field_info)
refLyr = arcpy.mapping.Layer('temp_layer')
refLyr.name = 'your target layer name'
arcpy.ApplySymbologyFromLayer_management(refLyr, LayerNeedsFieldsTurnedOff)
arcpy.mapping.UpdateLayer(df, LayerNeedsFieldsTurnedOff, refLyr, False)
mxd.save()
print 'cleaning up-'
if arcpy.Exists('temp_layer'):
print '\'temp_layer\' still in memory...deleting now...'
arcpy.Delete_management('temp_layer')
print 'deleting obj refs...'
del mxd, LayerNeedsFieldsTurnedOff, refLyr
print 'done.'
desiredFields holds the fields by name you want to remain on (Python list). In this case, the index is fetched by looping over the count returned from fieldInfo.count (is the same return as length of a list). The rest is basically closely similar to what you were already thinking, substituting the fieldInfo obj using MakeFeatureLayer - the exception here is the code was written to use a layer obj to update a feature layer in the map.
-
Just a point of conceptual distinction to add: Fields aren't deleted in a layer (or feature layer); they are either made visible or hidden. The underlying source will still store the field, unless of course you delete it from the source. Certain fields (like an OBJECTID field) are not 'delete-able'.T. Wayne Whitley– T. Wayne Whitley2017年02月27日 00:40:00 +00:00Commented Feb 27, 2017 at 0:40
-
Thank you T Wayne Whitley - I saw this earlier today through my google searches but am getting the same error I was earlier when I tried it - Invalid value type for parameter where_clause. I figure I must not be executing it right. My previous efforts were going great until I found out I couldn't delete the ObjectID fields. That lead me down the rabbit hole of creating a layer file, trying to turn the fields off, and than shapefile conversion.user92389– user923892017年02月27日 00:44:40 +00:00Commented Feb 27, 2017 at 0:44
-
Incidentally, you seem to be confusing the sources with the layers that serve as 'pointers'. The fieldInfo object can be edited in a way to add/remove fields, however persisting changes of that nature must be exported to a new source, i.e. Shapefile or gdb feature class or table, etc...and, again, you cannot remove such fields as FID in the source.T. Wayne Whitley– T. Wayne Whitley2017年02月27日 00:50:10 +00:00Commented Feb 27, 2017 at 0:50
-
Right now I have it set to create the layer file from a shapefile, turn the fields off, and than convert back to a shapefile.user92389– user923892017年02月27日 00:52:43 +00:00Commented Feb 27, 2017 at 0:52
-
I suggest you try the code above, after editing field names etc accordingly as needed. Notice the ApplySymbologyFromLayer line....if you apply this technique to an appropriate layer in your map, you should find it 'turns off' field visibility.T. Wayne Whitley– T. Wayne Whitley2017年02月27日 00:55:29 +00:00Commented Feb 27, 2017 at 0:55
While looking into how to make fields visible (or hidden) with arcpy, I came across this thread. The above answers don't work very well (in my attempts) with ArcGIS Pro 3.1, but the below code I modified does:
desc = arcpy.Describe(Your_original_layer)
if desc.dataType == "FeatureLayer":
field_info = desc.fieldInfo
# desc.OIDFieldName is the name of the 'FID' field
fieldsToHide = [desc.OIDFieldName, 'your_field', 'your_field']
for i in range(0, field_info.count):
if field_info.getFieldName(i) in fieldsToHide:
field_info.setVisible(i, "VISIBLE")
arcpy.MakeFeatureLayer_management(Your_original_layer, "New_layer", "", "", field_info)
Explore related questions
See similar questions with these tags.