2

I'm trying to search through a directory of shp files for any shp file with a specific field that is empty. Here is my code as of right now.

import arcpy
from arcpy import env
env.workspace = r'C:\Workspace\Data_State\MS\Administrative_Boundaries\2013_complete'

fc = arcpy.ListFeatureClasses('*.shp')
fields = "MP_TYPE"


for field in fields:
    #get list of values
    values = [r[0] for r
              in arcpy.da.SearchCursor (fc, field)
              if r[0] != None]

    #Check if list is empty
    if not values:
        print field, "is empty"

I keep getting a runtime error 'in_table' is not a table or a featureclass I've looked at other examples on here and can't get any of them to work.

Ideally:

  • the script would cycle through the directory
  • print the shp file with the empty attribute value
  • then move on because I'm going to have many directories to search through.

Unfortunately, I can't put the shp files into a gdb for this. I'm using 10.3, so if possible I'd like to use arcpy.da.SearchCursor. I just can't seem to get it to work with the shp files.

0

This is to add on to the other answers. Shapefiles do support NULL dates. Also, checking for '' only works for string fields. If a numeric column is NULL and is converted to a shapefile, all the NULLs are converted to zeros. With string fields, sometimes NULLs will get converted to a string like "NULL".

This is a script that will show you if a column of any type is empty. It is up to you to define what NULL means to you. That is, in the 7th line of code, you fill in what the script is checking as NULL.

Also, note that the script checks to see if the field actually exists in the shapefile. Also, column names can be case sensitive, so you should always account for the case. This snippet is part of a much larger script that accommodates both geodatabases and shapefiles, tables, folders, feature datasets and feature classes, so it is written accordingly.

import arcpy, os
from arcpy import env

in_workspace = r'C:\Workspace\Data_State\MS\Administrative_Boundaries\2013_complete'
arcpy.env.workspace = in_workspace
field_name_list = ["MP_TYPE"]
nullvalues = ["", " ", None, 0]

# COLLECT FEATURE CLASSES AND TABLES FROM WORKSPACE TREE
feature_classes = []
walk = arcpy.da.Walk(in_workspace, datatype='FeatureClass')
for dirpath, dirnames, filenames in walk:
    for filename in filenames:
        feature_classes.append(os.path.join(dirpath, filename))

if len(feature_classes) > 0:

    FCs = arcpy.ListFeatureClasses("*")
    for fc in FCs:
        desc = arcpy.Describe(fc)
        print desc.name
        fc_path = desc.catalogPath
        lfields=arcpy.ListFields(fc_path)
        for f in lfields:
            print f.name
            if f.name.upper() in field_name_list:
                rowCount = 0
                with arcpy.da.SearchCursor(fc_path, f.name) as cur:
                    for row in cur:
                        v = row[0]
                        if not(v in nullvalues):
                            rowCount += 1
                if rowCount == 0:
                    print f.name, "is empty"
                else:
                    print f.name, "is NOT empty"
else:
    print "feature classes not found"
  • Sorry, I just noticed that you have multiple workspaces. You could batch this script with the batch grid (make it a script tool and right-click, select Batch). Or you could incorporate it into a Walk, like described above. That will only work if your workspaces are in a tree. Keep in mind that the data type for a shapefile is "ShapeFile", not "FeatureClass". Also, you can find shapefile workspaces like this: folders = arcpy.ListWorkspaces("*", "Folder") – RHB Mar 15 '16 at 13:54
  • Actually, I think I am wrong about the data type for Walk. With describe, the data type comes out "ShapeFile", but I think it is "FeatureClass" for Walk. – RHB Mar 15 '16 at 14:06
  • So far this is the only answer that I've been able to produce so much as a lock file of one of the shp files in the folder. I'm going to keep trying different things until I get something to work the way I'm hoping. I'll post the script I used that works when I find it. – morgan Mar 15 '16 at 20:52
  • Morgan, I updated the script 1) to walk through from a top directory through subdirectories and collect all the feature classes, and 2) to provide some messages so you can tell if it is at least iterating through all the shapefiles like it should. I use a variation of this script frequently, so it should work. – RHB Mar 16 '16 at 14:56
  • RHB, Nice! This one goes through the shp files nicely, but for some reason it's not catching a field as empty if there are only a few features with the field empty. I'm thinking it might be better for me to tweak it a bit to look for values that don't equal the correct values – morgan Mar 16 '16 at 15:07
2

ListFeatureClasses outputs a list of feature classes, not a single one. So the variable fc, if you printed it, would be a long list of names. That's what's tripping up the process.

I recommend putting your "for field in fields" in another for loop for c in fc: and see if that works better. Then you'll be feeding the searchcursor one shapefile at a time instead of all at once.

  • I'm still getting the same error when I add for c in fc: – morgan Mar 14 '16 at 21:03
  • Out of curiosity, what happens when you enter the code up to "for c in fc" into the Python window in ArcMap or your IDE, and then put a "print c.name" in the "for c in fc:" loop? What line of your script is your runtime error triggering on? – Andy Bradford Mar 14 '16 at 21:07
  • when I add print c.name, I get a 'unicode' object has no attribute 'name' on line 11 – morgan Mar 14 '16 at 21:32
2

The biggest problem with your script is that you are looking for values in a list of feature classes, you need to iterate them as Andy said, also you're looking for None where None is not supported... Shapefiles do not support null values, only 0 or empty string ('').

import arcpy
from arcpy import env
env.workspace = r'C:\Workspace\Data_State\MS\Administrative_Boundaries\2013_complete'

fcList = arcpy.ListFeatureClasses('*.shp')
fields = "MP_TYPE"

for fc in fcList:
    for field in fields:
            #get list of values
            values = [r[0] for r in arcpy.da.SearchCursor (fc, field)]

            #Check if list is empty
            if '' in values:
                    print ("Feature class {0} has an empty value in field {1}".format(fc,field))

will work for string fields, if your field is numeric you need to search for 0 in the list. Try to get into the habit of parenthesizing your print statements, in later versions you must do that; also assuming you want to add fields to it later you can print that using the format statement.

As you said you wanted to go through a lot of folders and perhaps many fields here is a script with arcpy.da.walk which may help... arcpy Walk is like os walk except it only iterates GIS data, so will 'walk' down the tree and test every feature class in the folder and all subfolders.

import arcpy
from arcpy import env
env.workspace = r'C:\Workspace\Data_State\MS\Administrative_Boundaries\2013_complete'

fields = "MP_TYPE"

for (folder,subDirs,fcList) in arcpy.da.Walk(env.workspace,datatype = 'FeatureClass')
    for fc in fcList:
        for field in fields:
                #get list of values
                values = [r[0] for r in arcpy.da.SearchCursor (fc, field)]

                #Check if list is empty
                if '' in values:
                        print ("Feature class {0} in folder {1} has an empty value in field {2}".format(fc,folder,field))
  • A much better answer than mine - I'd forgotten that bit about shapefiles not supporting Null values. – Andy Bradford Mar 15 '16 at 13:06

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.