Keeping Object ID field only and deleting any other field

656
9
Jump to solution
08-29-2019 10:31 AM
ConnorMcivor
New Contributor III

Pretty straight forward. I am building a tool that outputs an Excel file with XYZ data pertaining to a polyline route. Parameters include:

Input Points (points have been generated along a line fc every 1 meter)

Input DEM

Output Location for Excel sheet

The tool takes the input points, make a copy, SUPPOSED TO DELETE ALL FIELDS EXCEPT OBJECT ID, uses Add XY tool, then uses Extract Value to get the elevation, and finally exports the table to an Excel file. So the issue is when i am trying to delete all the fields except Object ID. All i get is a runtime error: error executing tool. I have tried many versions of my code to delete the fields. Here is one example:

SaveList 			= ["OBJECTID", "OBJECT_ID", "ObjectID"]

for feild in arcpy.ListFields(Copied_Points):
	if feild.name not in SaveList:
		arcpy.DeleteField_management(Copied_Points, feild)
del field‍‍‍‍‍‍

Any thoughts on how to make this work? Thanks guys/gals.

Tags (4)
0 Kudos
1 Solution

Accepted Solutions
ConnorMcivor
New Contributor III

Thanks everyone for your input... I used a combination of a few of the things suggested here and added other elements in to the mix. I am now trying to make it so that the user can CHOOSE feilds that they want to keep in the output file. An example of the code now:

{

Copy_KP = arcpy.GetParameterAsText(#)

Keep_Fields = arcpy.GetParameterAsText(#)    # Feild parameter, multivalue, obtained from original data source

keepList = []

for item in Keep_Fields:
      keepList.append(item)

fieldNames = [f.name for f in arcpy.Describe(Copy_KP).Fields if not (f.type in ["OID", "Geometry"] or f.name in ["Shape_Length", "Shape_Area"] or f.name.upper() in keepList )]
if fieldNames:
      arcpy.DeleteField_management(Copy_KP, fieldNames)

}

I set the "Keep_Fields" parameter as "Field" type with multivalue enabled. The Keep_Fields part isn't working yet but the fields all delete except the "OID". So at least there is that. I will keep working at it next week.

Again, thanks everyone for the help!

View solution in original post

0 Kudos
9 Replies
DanPatterson_Retired
MVP Esteemed Contributor

You have an issue with getting the field name 

OBJECTID is for file geodatabases

otherwise you might want to use a 'describe' object and get the id from there

Table properties—ArcPy Functions | ArcGIS Desktop 

0 Kudos
ConnorMcivor
New Contributor III

Ok so yes I only work with file geodatabases when working on anything related to custom built tools. I am aware that the OID and Shape fields are required. I just need to strip away any tabular data and keep the essentials. Did I miss something in what you had suggested? 

0 Kudos
RandyBurton
MVP Regular Contributor

Since you are using ListFields you can also try:

     if feild.type != "OID" :

Do you also wish to delete any geometry?

0 Kudos
ConnorMcivor
New Contributor III

I just need the required fields for file geodatabases. All non-required fields need to be gone. I now realise that i cannot delete Shape either and that is fine. So keep OID and SHAPE fields. All else needs to be removed. I dont want to hard code it because the input will not be the same fields each time.

0 Kudos
RandyBurton
MVP Regular Contributor

If ListFields is indicating a type of OID, then use the name property to delete it. To skip both object ID  and geometry fields in your deletion, you might try:

field_types = ['OID', 'GEOMETRY'] # field types to ignore

#...
for feild in arcpy.ListFields(Copied_Points): # note spelling of "feild"
    if feild.type.upper() not in field_types:
        # then delete field.name‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
RandyBurton
MVP Regular Contributor

There is also the .required property.  I haven't tested it, but it probably returns a True/False. This would be a more generic test.

    if feild.required is false: # perhaps: == 'False'‍‍‍‍
JoshuaBixby
MVP Esteemed Contributor

The problem with "required" fields is that non-system fields can be required if configured that way when created.

ConnorMcivor
New Contributor III

Thanks everyone for your input... I used a combination of a few of the things suggested here and added other elements in to the mix. I am now trying to make it so that the user can CHOOSE feilds that they want to keep in the output file. An example of the code now:

{

Copy_KP = arcpy.GetParameterAsText(#)

Keep_Fields = arcpy.GetParameterAsText(#)    # Feild parameter, multivalue, obtained from original data source

keepList = []

for item in Keep_Fields:
      keepList.append(item)

fieldNames = [f.name for f in arcpy.Describe(Copy_KP).Fields if not (f.type in ["OID", "Geometry"] or f.name in ["Shape_Length", "Shape_Area"] or f.name.upper() in keepList )]
if fieldNames:
      arcpy.DeleteField_management(Copy_KP, fieldNames)

}

I set the "Keep_Fields" parameter as "Field" type with multivalue enabled. The Keep_Fields part isn't working yet but the fields all delete except the "OID". So at least there is that. I will keep working at it next week.

Again, thanks everyone for the help!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Instead of trying to guess ahead of time which fields you can and can't delete from various data sources, just wrap your code in Python try/expect block:

import arcpy
import arcgisscripting

fc = # path to feature class
desc = arcpy.Describe(fc)

for fld in desc.fields:
  try:
      arcpy.DeleteField_management(fc, fld.name)
  except arcgisscripting.ExecuteError as e:
       print("Could not delete: {}".format(fld.name))