1

The current code I have simply lists ALL fields in the feature class and seems to ignore my logic of if row[0] is not None: Why does it do this?

fields = arcpy.ListFields('\\\\Bvweb104draco\\e\\03_MapServices\\SDE_CONNECTIONS\\bvcolumbusdev.sde\\bvcolumbusdev.sde.Telecom\\bvcolumbusdev.sde.AREAS')
featureClass = '\\\\Bvweb104draco\\e\\03_MapServices\\SDE_CONNECTIONS\\bvcolumbusdev.sde\\bvcolumbusdev.sde.Telecom\\bvcolumbusdev.sde.AREAS'

with arcpy.da.SearchCursor(featureClass, str(fields)) as cursor:
    for field in fields:
        if row[0] is not None:
            print(field.name)

I want the cursor to loop through each field and if it stumbles upon a row that has a value other than NULL, print that field name.

6
  • so what exactly does it do? Your logic is faulty....row[0] is the 1st value of the cursor tuple of values returned from the table row values; field is the field object whether null (none) or not. Commented Jan 9, 2019 at 19:53
  • I intended it to look at each field in the feature class and loop through each row of said field and if a row has a value other than NULL print the field name. I want to find the fields that have all NULL values.
    – GIS_GOD
    Commented Jan 9, 2019 at 19:56
  • 2
    your logic is somewhat backwards - you don't have to loop on fields because the value tuple returned corresponds to the order of values. Also, str(fields) doesn't make sense...here you could use a list comprehension of field.name to form the fields to feed to your SearchCursor, but actually the default is to return all field values (so you can skip this step) Commented Jan 9, 2019 at 19:58
  • 2
    think you'll find an existing answer here: gis.stackexchange.com/questions/158199/… Commented Jan 9, 2019 at 20:06
  • 2
    Similar solutions here as well: gis.stackexchange.com/questions/305274/…
    – mikewatt
    Commented Jan 9, 2019 at 20:55

3 Answers 3

1

Considering you're using an enterprise database leverage that power by creating a feature layer with a where clause and then getting the count of features (rows) in that layer with GetCount_management.

Try this code:

featureClass = '\\\\Bvweb104draco\\e\\03_MapServices\\SDE_CONNECTIONS\\bvcolumbusdev.sde\\bvcolumbusdev.sde.Telecom\\bvcolumbusdev.sde.AREAS'
fields       = arcpy.ListFields(featureClass) # less typing this way, less chance of mistakes

for ThisField in fields:
    if ThisField.isNullable:        # Only fields that *can* contain a value of null
        # make a feature layer with a where clause
        arcpy.MakeFeatureLayer_management(featureClass,'look_4_NotNull','{} is not null'.format(ThisField.name))

        # get the count of features that contain non-null values
        if int(arcpy.GetCount_management('look_4_NotNull').getOutput(0)) > 0:
            # if at least one row has a non-null value print out the field name
            print ThisField.name

        # clean up, delete the layer (does not affect the feature class, just the layer)
        arcpy.Delete_management('look_4_NotNull')

Enterprise databases perform very fast queries, that's one of the reasons why a user would consider the extra effort over file/personal geodatabases but certainly not the only reason, depending on the number of rows that would have been iterated this approach is likely to be much faster than using any kind of search cursor (arcpy.SearchCursor or arcpy.da.SearchCursor).

2
  • I'll give this a try, think I'll comment out the arcpy. Delete_management part of it though because the field needs to stay, just looking for a list.
    – GIS_GOD
    Commented Jan 10, 2019 at 15:15
  • 1
    The Delete_management only affects the layer, as i am reusing the layer name it's important to remove the layer object, as mentioned in the preceding comment, before creating a new one if you don't have arcpy.env.overwriteOutput = True by default or previously in the script or you will get an error object already exists. Commented Jan 13, 2019 at 23:06
0

This seems to work, but it vastly beyond my current understanding of Python.

fc = '\\\\Bvweb104draco\\e\\03_MapServices\\SDE_CONNECTIONS\\bvcolumbusdev.sde\\bvcolumbusdev.sde.Telecom\\bvcolumbusdev.sde.AREAS'

#getting list of fields with nulls allowed (those that don't allow nulls won't have nulls so we can skip them already now)
not_null_fields = [field.name for field in arcpy.ListFields(fc) if field.isNullable != "False"]

#getting a dict {field_name : [list of all values]}
fields_dict = {field: list(set([feature[not_null_fields.index(field)] for feature in arcpy.da.SearchCursor(fc,not_null_fields)])) for field in not_null_fields}

#finding out which fields contain only None
null_fields = [k for k,v in fields_dict.iteritems() if v == [None]]

nullList = []

for field in null_fields:
    nullList.append(str(field))
1
  • Not sure why it got a -1, but this will work for anyone trying to accomplish the same task, just change the feature class variable obviously.
    – GIS_GOD
    Commented Jan 9, 2019 at 21:17
-2

I don't have ArcGIS on this computer but looking through the docs I think this will do what you want, or at least be close.

fields = arcpy.ListFields('\\\\Bvweb104draco\\e\\03_MapServices\\SDE_CONNECTIONS\\bvcolumbusdev.sde\\bvcolumbusdev.sde.Telecom\\bvcolumbusdev.sde.AREAS')
featureClass = '\\\\Bvweb104draco\\e\\03_MapServices\\SDE_CONNECTIONS\\bvcolumbusdev.sde\\bvcolumbusdev.sde.Telecom\\bvcolumbusdev.sde.AREAS'

semicolon_fields = ";".join(fields)

with arcpy.da.SearchCursor(featureClass, fields=semicolon_fields) as cursor:
    for row in cursor:
        for field in fields:
            if row.getValue(field):
                print(field.name)

First off, according to the docs, you have to pass a semicolon-delimited string to the SearchCursor constructor, I added that with fields = ";".join(fields).

Next, because fields is a keyword argument, and is not the first one, you have to explicitly reference it by name (fields=semicolon_fields). Although unless you want to only look at selected fields, you can just skip this parameter entirely.

After that, you have to iterate through the rows, before iterating through the fields (for row in cursor:)

Finally, according to the docs again, you get a field value by calling row.getValue(<field_name>)

1
  • 1
    row.getValue is not possible with a DA Cursor
    – Vince
    Commented Jan 9, 2019 at 23:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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