Select to view content in your preferred language

How do I delete specific fields in multiple feature classes (not necessarily the same fields)?

1947
10
05-08-2023 01:12 PM
bcarpenter87
New Contributor II

I was given this script to modify it to specify certain fields to delete within certain feature classes. How it is now, all fields I put in the list will be deleted in the specified geodatabase. What would I include in this script to further specify that certain fields within a feature class are deleted while certain other fields in another feature class are deleted, etc.? I am a very beginner programmer and intern and my boss gave me this to experiment with and work on, suggesting geonet/ESRI community as a good resource. I've included the script.

Thank you for any help,

Ben

0 Kudos
10 Replies
by Anonymous User
Not applicable

It's close, but ran individually won't do what you want. The red squigglies in the pycharm means the variable is not defined. The complete script to run looks like:

import re
import arcpy
import os
from arcpy import env

env.workspace = r"C:\.gdb"
p = arcpy.mp.ArcGISProject(r'C:\project.aprx')
m = p.listMaps('Final')[0]
fcList = m.listLayers()

fcFieldDict = {}

# Create the dictionary of fields from the txt file by splitting the spaces.
with open(r'C:\path to specificdeletefields.txt', 'r') as txt:
    for line in txt:
        # split on two or more spaces
        # \s <- any whitespace
        # {2,} <- cnt to match
        splt = re.compile('\s{2,}')
        vals = splt.split(line)
        try:
            if vals[1]:  # don't append the None's to the list
                if not fcFieldDict.get(vals[0]):
                    fcFieldDict[vals[0]] = [vals[1].strip()]
                else:
                    if vals[1] not in fcFieldDict[vals[0]]:  # avoid appending duplicates
                        fcFieldDict[vals[0]].append(vals[1].strip())

        except:
            arcpy.AddMessage(vals)

# Check the dictionary
for k, v in fcFieldDict.items():
    arcpy.AddMessage(f'fc: {k}, fields to drop:{v}')

# This method is inplace and may take a while to go over each fc
for fc in fcList:
    fcDesc = arcpy.Describe(fc)
    fieldsToDrop = fcFieldDict.get(fcDesc.nameString)
    if fieldsToDrop:
        fcPath = fcDesc.path
        arcpy.DeleteField_management(fcPath, fieldsToDrop)
        arcpy.AddMessage(f'{fc} Dropped {fieldsToDrop}!')
    else:
        arcpy.AddMessage(f'Didnt find matching fc for {fc}')

# This method creates a field map and copies the featureclasses to a new output without the dropped fields
# for fc in fcList:
#     fcDesc = arcpy.Describe(fc)
#     fieldsToDrop = fcFieldDict.get(fcDesc.nameString)
#     if fieldsToDrop:
# 
#         fcPath = fcDesc.path
# 
#         fldMap = arcpy.FieldMappings()
#         # Creating field maps for the two files
#         fldMap.addTable(fc)
# 
#         # Removing unwanted fields
#         for field in fldMap.fields:
#             if not field.required and field in fieldsToDrop:
#                 fldMap.removeFieldMap(fldMap.findFieldMapIndex(field.name))
# 
#         arcpy.FeatureClassToFeatureClass_conversion(fcPath, r'path to other.gdb', os.path.basename(fcDesc.name), '', fldMap)
#     else:
#         print(f'Didnt find matching fc for {fc}')

Swapping out the method that you want to user (drop in place or export to new fc)  The

fcDesc = arcpy.Describe(fc)
fieldsToDrop = fcFieldDict.get(fcDesc.nameString)
fcPath = fcDesc.path

lines will get the featureclass name/path for you by looking at the layer properties, so you wont (shouldn't) have to add the underscores.

You can test it by commenting out the delete at line 42 so it wont actually delete the field. It'll show you at least which layers are not mapped to the featureclass in the gdb.

0 Kudos