I need to remove fields within file GDB and SDE databases that contain only empty or null values. I was hoping to do this for an entire database at a time rather than per feature class. The code below shows the best of what I have so far. It does not, however, accomplish what I had hoped. I am somewhat new to Python and am using ArcMap 10.3.1.
import arcpy
from arcpy import env
env.workspace = r"C:\New Folder\Default.gdb"
def DelFields(path):
env.workspace = path
# first need to point to FCs within DSs
datasets = arcpy.ListDatasets(feature_type='All')
datasets = [''] + datasets if datasets is not None else []
for ds in datasets:
for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
# list comp syntax:
# [{code}var{code} for var in [list] if var{logic test}].
fieldList = [f.name for f in arcpy.ListFields(fc) if f.type ==
"Short" or "Long" or "Float" or "Double" or "Text" or
"Date" or "Blob" or "Raster" or "Guid"] # "All" did not work
print fieldList # to see what I have so far
if fieldList: # this is a bit of a long shot I think
# The UpdateCursor line gives error:
# TypeError: 'field_names' must be string or non empty sequence of strings
with arcpy.da.UpdateCursor(fc, [fieldList]) as cursor:
for row in cursor:
for i in range (len(fieldList)):
if row[i].rstrip() == "": # trying to find empties
arcpy.DeleteField_management(path, fieldList)
elif row[i] == "": # trying to find Nulls
arcpy.DeleteField_management(path, fieldList)
cursor.updateRow(row)
DelFields(r"C:\New Folder\Default.gdb")
Answer
Try this; see the comments for explanation.
import os
import arcpy
from arcpy import env
def DelFields(path):
env.workspace = path
# Get a list of feature classes directly (i.e., not within feature datasets)
# the geodatabase
fcs = arcpy.ListFeatureClasses()
# Add the relative paths of feature classes that are within feature
# datasets
fcs.extend([os.path.join(fd, fc) for fd in arcpy.ListDatasets() for fc in arcpy.ListFeatureClasses(feature_dataset=fd)])
# Iterate over the feature classes
for fc in fcs:
# Test whether the field is required--rather than testing the field type
fieldList = [f.name for f in arcpy.ListFields(fc) if not f.required]
# Iterate over the fields
for field in fieldList:
# Set a test variable to False
keep = False
# Iterate over each feature; if it has a non-null value, then set
# the test variable to True and then break out of the cursor
with arcpy.da.SearchCursor(fc, field) as cursor:
for row in cursor:
v = row[0]
if v is not None or \
(isinstance(v, basestring) \
and (v.lower.strip() != ''\
or v != '')):
keep = True
break
# If the test variable was unchanged, delete the field
if keep is False:
arcpy.DeleteField_management(fc, field)
DelFields(r"C:\tlax490\data\temp\temp.gdb")
EDIT: I've changed the if statement within the cursor to test for your desired null-like strings.
To catch similar cases that you might otherwise miss, you can determine whether the value is a string, and if so, lowercase it and then remove empty spaces on the outsides. If the result is your bracketed null or an empty string, then it will be considered null.
No comments:
Post a Comment