3

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?

6
  • 2
    You 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
    Feb 26 '17 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
    Feb 26 '17 at 23:36
  • 1
    The first argument of setVisible is an integer, the index of the field to set not the name of the field to set. Feb 26 '17 at 23:36
  • Use findFieldByName to get index Feb 26 '17 at 23:38
  • 3
    FYI, 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
    Feb 26 '17 at 23:40
4

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.

2
  • 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
    Feb 27 '17 at 1:38
  • Do you know if arcpy.Describe is only way to return a FieldInfo object?
    – fatih_dur
    Mar 27 '19 at 7:02
2

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.

5
  • 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'. Feb 27 '17 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
    Feb 27 '17 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. Feb 27 '17 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
    Feb 27 '17 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. Feb 27 '17 at 0:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.