I've got a Python script that "cleans up" a feature class by renaming fields to something more legible -- add a new field (e.g. "DistrictName"), copy data from old field (e.g. "DISTNAM") to new field, and delete the old field. This is done for a lot of fields, so I built functions:
def delete_field(tbl, fieldName):
arcpy.DeleteField_management(tbl, fieldName)
def replace_field(tbl, newFieldName, oldFieldName, dataType):
arcpy.AddField_management(tbl, newFieldName, dataType)
with arcpy.da.UpdateCursor(tbl, [newFieldName, oldFieldName]) as cursor:
for row in cursor:
row[0] = row[1]
cursor.updateRow(row)
delete_field(tbl, oldFieldName)
But there's a subsequent step in the Python script that is exporting this feature class to an Excel spreadsheet, and part of the process builds a list of the fields to be used to create a header row of column names.
data_description = arcpy.Describe(dataset_name)
fieldnames = [f.name for f in data_description.fields if f.type not in ["Geometry", "Raster", "Blob"]]
When I look at the resulting feature class in ArcMap, all the old field names have been deleted, which is exactly what I would expect. When Python does that Describe
step, it sees both the new AND the old field names -- but it breaks when attempting to copy an old field, since the data does not actually exist.
What step can I add between deleting and listing to "update" the feature class fields
so it only lists the existing fields, and not any fields which were recently deleted?
EDIT: I pulled the Describe
portion out of its function and put it directly after the sequence of replace_field
operations. Also tried using arcpy.ListFields
instead of the Describe
method.
replace_field(tableName, "District_Name", "DISTRICTNAME", "TEXT")
replace_field(tableName, "District_Number", "DISTRICT", "LONG")
replace_field(tableName, "LocalOffice_Name", "LOCALOFFICENAME", "TEXT")
replace_field(tableName, "Substation_Number", "SUBSTATIONID", "LONG")
replace_field(tableName, "FeederID", "CIRCUITID", "LONG")
replace_field(tableName, "OH_SinglePhase_CircuitMiles", "OH_SINGLEPHASE", "DOUBLE")
replace_field(tableName, "OH_TwoPhase_CircuitMiles", "OH_TWOPHASE", "DOUBLE")
replace_field(tableName, "OH_ThreePhase_CircuitMiles", "OH_THREEPHASE", "DOUBLE")
replace_field(tableName, "OH_Total_CircuitMiles", "OH_TOTALCIR", "DOUBLE")
replace_field(tableName, "UG_SinglePhase_CircuitMiles", "UG_SINGLEPHASE", "DOUBLE")
replace_field(tableName, "UG_TwoPhase_CircuitMiles", "UG_TWOPHASE", "DOUBLE")
replace_field(tableName, "UG_ThreePhase_CircuitMiles", "UG_THREEPHASE", "DOUBLE")
replace_field(tableName, "UG_Total_CircuitMiles", "UG_TOTALCIR", "DOUBLE")
data_description = arcpy.Describe(tableName)
fieldnames = [f.name for f in data_description.fields if f.type not in ["Geometry", "Raster", "Blob"]]
print fieldnames
apyListFields = arcpy.ListFields(tableName)
print apyListFields
The resulting list of fields from both Describe
and ListFields
is the same -- and all the field names in caps (e.g. DISTRICTNAME
) are deleted, but still showing up as field names.
[u'OBJECTID', u'District_Name', u'District_Number', u'LocalOffice_Name', u'Substation_Number', u'FeederID', u'OH_SinglePhase_CircuitMiles', u'OH_TwoPhase_CircuitMiles', u'OH_ThreePhase_CircuitMiles', u'OH_Total_CircuitMiles', u'UG_SinglePhase_CircuitMiles', u'UG_TwoPhase_CircuitMiles', u'UG_ThreePhase_CircuitMiles', u'UG_Total_CircuitMiles', u'UG_TOTALCIR', u'UG_THREEPHASE', u'UG_TWOPHASE', u'UG_SINGLEPHASE', u'OH_TOTALCIR', u'OH_THREEPHASE', u'OH_TWOPHASE', u'OH_SINGLEPHASE', u'CIRCUITID', u'SUBSTATIONID', u'LOCALOFFICENAME', u'DISTRICT', u'DISTRICTNAME']
[u'OBJECTID', u'District_Name', u'District_Number', u'LocalOffice_Name', u'Substation_Number', u'FeederID', u'OH_SinglePhase_CircuitMiles', u'OH_TwoPhase_CircuitMiles', u'OH_ThreePhase_CircuitMiles', u'OH_Total_CircuitMiles', u'UG_SinglePhase_CircuitMiles', u'UG_TwoPhase_CircuitMiles', u'UG_ThreePhase_CircuitMiles', u'UG_Total_CircuitMiles', u'UG_TOTALCIR', u'UG_THREEPHASE', u'UG_TWOPHASE', u'UG_SINGLEPHASE', u'OH_TOTALCIR', u'OH_THREEPHASE', u'OH_TWOPHASE', u'OH_SINGLEPHASE', u'CIRCUITID', u'SUBSTATIONID', u'LOCALOFFICENAME', u'DISTRICT', u'DISTRICTNAME']
with
statement's frame, and the call todelete_field()
immediately after it. Have you tried issuing the call todelete_field()
outside of thereplace_field()
definition in this case? Otherwise, the code reads fine in my opinion, there is no obvious reason why it should not work as-is; in other words, something is happening that is not immediately the script's fault.delete_field()
without involving thereplace_field()
function, and ArcPy still sees the "deleted" field...dataset_name
. It would also be calledtbl
except I didn't write it, it's from somebody else's module.