4

I'm currently formatting our GIS data for use in a mobile app. The purpose of altering the data is to reduce the output file size that's imported into the app. I need to delete many fields from many feature classes. I will need to run this script about every two months to provide updated data.

The first part of my script copies the feature classes from our SDE geodatabase to a file geodatabase using arcpy.FeatureClassToFeatureClass_conversion(). This function has a field_mapping parameter which I'm not very familiar with.

What would be the quickest way to delete many fields from many feature classes?

Using the field_mapping parameter, or just using arcpy.DeleteField_management()? I would think field_mapping.


The real problem is that I want to remove around 30 fields from each feature class, and only keep around 4-5.

With field_mapping, (I haven't researched this yet) is there a way to simply state only the fields I want to keep without listing all the fields I want to remove too?

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked May 7, 2015 at 16:28
2
  • If the fields are the same every time you need to do this, I would probably script it out using a "ListFeatureClasses" and "deleteField" loop and run it at night when I'm not working. Commented May 7, 2015 at 16:56
  • However, the answer provided below by crmackey could be implemented with a script as well. Commented May 7, 2015 at 16:59

4 Answers 4

7

Another alternative is to create a feature layer containing only the fields you want, then use arcpy.CopyFeatures_management() or arcpy.FeatureClassToFeatureClass_conversion() to copy the result to a new feature class.

I've written a function called make_skinny() (with two wrappers, make_skinny_feature_layer() and make_skinny_table_view()) that takes a list of the fieldnames you want to keep and returns a layer/view with only those fields. Also accepts an optional definition query to subset the records.

def make_skinny(is_geo, in_obj, out_obj, keep_fields_list=None, where_clause=''):
 ''' Make an ArcGIS Feature Layer or Table View, containing only the fields
 specified in keep_fields_list, using an optional SQL query. Default
 will create a layer/view with NO fields. '''
 field_info_str = ''
 input_fields = arcpy.ListFields(in_obj)
 if not keep_fields_list:
 keep_fields_list = []
 for field in input_fields:
 if field.name in keep_fields_list:
 field_info_str += field.name + ' ' + field.name + ' VISIBLE;'
 else:
 field_info_str += field.name + ' ' + field.name + ' HIDDEN;'
 field_info_str.rstrip(';') # Remove trailing semicolon
 if is_geo:
 arcpy.MakeFeatureLayer_management(in_obj, out_obj, where_clause, field_info=field_info_str)
 else:
 arcpy.MakeTableView_management(in_obj, out_obj, where_clause, field_info=field_info_str)
 return out_obj
# Wrapper functions for make_skinny()
def make_skinny_feature_layer(fc, lyr, keep_fields_list=None, where_clause=''):
 return make_skinny(True, fc, lyr, keep_fields_list, where_clause)
def make_skinny_table_view(table, view, keep_fields_list=None, where_clause=''):
 return make_skinny(False, table, view, keep_fields_list, where_clause)
answered May 7, 2015 at 17:41
2
  • Do you know where the documentation is on how to format the field_info string? I haven't found anything. Commented May 14, 2015 at 2:34
  • 1
    I don't think I've ever seen any formal documentation for the string formatting, but I find the pure-Python method for constructing FieldMappings to be overwhelmingly tedious. I mostly reverse-engineered it by specifying a field mapping in a GUI tool and then doing "copy as Python snippet". I believe it's "old_field1_name new_field1_name VISIBLE/HIDDEN;old_field2_name new_field2_name VISIBLE/HIDDEN;...". Commented May 14, 2015 at 14:01
5

I have noticed that the DeleteField tool can be very slow when there are a lot of fields. One thing I have done in the past is created a template table that just has the fields I needed and just copy that blank table and use the arcpy.management.Append() to write features to the template table. Seemed to work pretty well.

answered May 7, 2015 at 16:36
4
  • Yeah, that's a great alternative. I'm going to see if anyone replies about the field mapping, otherwise I'll probably go this route. Thanks for the suggestion. Commented May 7, 2015 at 17:18
  • 1
    It would be a tedious work to create empty feature classes with all the fields data types and names, aliases though... Commented May 7, 2015 at 18:06
  • @AlexTereshenkov yeah, well I wouldn't create them manually. I'd export/import the XML like you had mentioned. Commented May 7, 2015 at 18:28
  • 1
    @ian, right, this makes sense. But then you would still need to delete the fields from the schema feature classes... if you have a chance - run SELECT INTO with SQL, this will make your life so much easier :D Commented May 7, 2015 at 20:29
5

To keep up with folks :) some alternatives

  1. Since you store your data in an enterprise geodatabase (or DBMS without Esri component) - why not take advantage of SQL? This is way faster than running any GP tool or arcpy (for copying data). Run some SELECT INTO statements limiting what columns you want to take and then run arcpy only to copy the tables with spatial column into file geodatabase feature classes. I would go for this if I could - in the SQL call you specify what columns you want to keep, just what you are asking for.

  2. If you will work with many feature classes, the fastest way I am aware of that will let you create a schema of the geodatabase (or some parts of it) is exporting a geodatabase schema to an XML workspace document (GP tool Export XML Workspace Document (Data Management)) and then importing it back to an empty file geodatabase. Delete fields for feature classes that were imported (it is faster to delete fields on empty feature class than on the one with features) with arcpy. Run Append GP tool to load data.

  3. Run FeatureClassToFeatureClass (Conversion) GP tool in ArcMap and set up in the Expression parameter 1 = 0 to not export any feature while deleting the unneeded fields in the Field Map parameter. Then copy the result as Python snippet and embed into your script; the drawback is huge field mappings which are large strings that are hard to work with. Append the source data with NO_TEST option - only data for the fields present in the target dataset will be appended.

answered May 7, 2015 at 17:58
1

Delete fields works fast when you have zero record. This script I wrote deletes fields much faster than just regular DeleteField arcpy function (when it comes to large dataset). The downside is that it has to create a new feature class.

def quick_delete_field(inputfc, fields2delete_lst, outputfc):
"""
select zero record from input, export, delete the fields, then append the original records
inputfc and outputfc should be full paths
fields2delete_lst must be a list and the values must match the fields in the inputfc
"""
import arcpy
# select zero record and export
arcpy.management.MakeFeatureLayer(inputfc, "temp_lyr")
arcpy.management.SelectLayerByAttribute("temp_lyr", "NEW_SELECTION", "OBJECTID IS NULL")
# export
arcpy.conversion.ExportFeatures("temp_lyr", outputfc)
# delete fields
arcpy.management.DeleteField(outputfc, fields2delete_lst)
# append
arcpy.management.Append(inputfc, outputfc, "NO_TEST")
answered May 25, 2024 at 2:09
1
  • You can use select while making feature layer Commented May 25, 2024 at 3:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.