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
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.