0

ArcGIS 10.4

I have a python (arcpy) script that is pulling values from a input list of fields for every featureclass in a geaodatabase (gdb) using a SearchCursor and is putting those values in a csv. The script works perfect for all featureclasses that have all the fields in the list. The script below is a thought process of how to capture all the field names in a list and do something if they are all present. This works but hits a stop if a field does not exist.

I've handled the " A column specified does not exist" using try/except exception in a different script that does not use the listFields so the script continues to run, but if even a single field does not exist in that featureclass the entire featureclass is skipped and is not present in the csv.

I need all records from all featureclasses in the csv even if a field does not exist in that featureclass. So something like if fieldname[0] not in fieldList put "field does not exist" where otherwise that fields value would be. I need this for every field in the list. The csv will have featureclassname, field1, field2, field3..etc.

import arcpy
import csv
import operator

arcpy.env.workspace = r"path\to\my\gdb"
newCSV = r"path\to\new\csv"
valueList = []

# Use the ListDatasets function to return a list of all feature datasets in the gdb:
datasetList = arcpy.ListDatasets("*", "Feature")  

with open(newCSV,'wb') as csvfile:
    for dataset in datasetList:

# Use the ListFeatureClasses function to return a list of all fc's in the gdb: 
    fcList = arcpy.ListFeatureClasses("*","",dataset)
        for fc in fcList:

        fieldname = ['field1', 'field2', 'field3']   
        fieldList = [f.name for f in arcpy.ListFields(fc)]  

        if fieldname[0] in fieldList and fieldname[1] in fieldList and fieldname[2] in fieldList:    

            with arcpy.da.SearchCursor(fc, fieldname) as cursor:
                row = cursor.next()


                while row:
                    valueList.append([[fc,row[0],row[1],row[2]]])

                    # #merge lists of lists
                    flattenList =  reduce(operator.concat,valueList)

                    writer = csv.writer(csvfile)
                    writer.writerows(flattenList)

                    row = cursor.next()
                    valueList = []
  • If only one or two fields are present you still want to write these to the csv? Then do: [f.name for f in arcpy.ListFields(fc) if f.name in ['field1', 'field2', 'field3']] and use this field list as input to the cursor – BERA Nov 19 '18 at 17:51
  • Maybe i'm missing something, but I am unable to make this work. I get the same stop iteration if the field does not exist. That featureclass is not written to the csv only the featureclasses where all fields are present. – csragis Nov 19 '18 at 20:37
1

Here's how I would simplify this. To maintain a consistent number of columns it should write a blank value if the field doesn't exist.

import arcpy
import csv

arcpy.env.workspace = r"path\to\my\gdb"
newCSV = r"path\to\new\csv"

datasetList = arcpy.ListDatasets("*", "Feature")

label_name = 'feature_class'
csv_fields = [label_name, 'field1', 'field2', 'field3']  # define desired csv fields

with open(newCSV,'wb') as csvfile:
    writer = csv.writer(csvfile)  # only need to instantiate this once
    writer.writerow(csv_fields)  # write the header

    for dataset in datasetList:
        fcList = arcpy.ListFeatureClasses("*","",dataset)
        for fc in fcList:
            with arcpy.da.SearchCursor(fc, '*') as cursor:  # include all available fields in the curor
                for row in cursor:
                    record = dict(zip(cursor.fields, row))  # create a dict of field name to field value
                    record[label_name] = fc  # add the feature class name to the dict
                    values = [record.get(key, None) for key in csv_fields]  # build the csv row, using None as the default value
                    writer.writerow(values)
  • This worked very well! Dictionaries are new for me and so I don't fully understand the code (my problem). With that said, I re-read my question and I forgot to specify I need the featureclass name as well. My code shows it but it's not in the question. Thank you! – csragis Nov 19 '18 at 20:17
  • Ah, sure, I've edited the answer to add that. Read up on dicts and if you have any specific questions shout 'em out! – mikewatt Nov 19 '18 at 21:01
  • This is brilliant! Thank you!! I really had hit a wall trying to over think this. I don't really understand the values = line but perhaps with a better understanding of the dicts it will make more sense. – csragis Nov 19 '18 at 21:28
  • No problem! Also check out list comprehension to understand that better – mikewatt Nov 19 '18 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.