SearchCursor directory and subdirectories using python

5211
1
Jump to solution
05-17-2015 12:35 AM
Yaron_YosefCohen
Occasional Contributor II

I work with arcmap 10.3 and python 2.7.8. I have more than 500 shapefiles located in many folders and subFolders. All Sub Folders are located in one large directory. I try with arcpy to detect all  shapefiles that have in their attribute table ,in field name "YEUD", the value 20. I search all shape files that begin with letters "mig". Finally i tried to print all the shapefiles that had been found with value 20 in it.

When i run this code i get en error:

import arcpy,os,sys,string,fnmatch
import arcpy.mapping
from arcpy import env

rootPath = r"C:\Project\layers"
pattern = 'mig*.shp'
fields = arcpy.ListFields(rootPath)
for root, dirs, files in os.walk(rootPath):
    for filename in fnmatch.filter(files, pattern):
        print( os.path.join(root, filename))
        for field in fields:
            with arcpy.da.SearchCursor(rootPath, field.name) as rows:
                for row in rows:
                    if field.name == 'YEUD':
                        if row == '20':
                             print( os.path.join(root, filename))

RuntimeError: ERROR 999999: Error executing function.
>>> 

I can't understand why it doesn't work ?

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
curtvprice
MVP Esteemed Contributor

Here's a revised script for you.

import os
import fnmatch
import arcpy
rootPath = r"C:\Project\layers" 
pattern = 'mig*.shp' 
for root, dirs, files in os.walk(rootPath): 
    for filename in fnmatch.filter(files, pattern): 
        shp = os.path.join(root, filename)
        if arcpy.ListFields(shp, "YEUD"):
            print("{} has YEUD field".format(shp)) 
            with arcpy.da.SearchCursor(shp, ["YEUD"]) as rows:
                for row in rows:
                    if row[0] == 20:
                        print("{} has a record with YEUD = 20".format(shp))
                        break

A few notes:

  • Line 1: I'm adopting the Python convention (PEP-8) of putting imports on their own line (easier to edit out modules you don't need that way).
  • Line 9: You were running arcpy.ListFields on a folder at the beginning. You need to run it on a dataset, inside the loop.
  • Line 9: The approach I normally use to test for field existence is to call arcpy.ListFields(tbl, field_name), if it comes back as an empty list  [], this means the field was not there. An empty list is interpreted as False when used in an if statement.
  • Line 11: The cursor is run here on the shape file table, not rootPath.
  • Line 15: Once I find a row with YEUD = 20, I jump out of the loop so I don't report more than once if there are multiple rows with that value.
  • ArcGIS 10.1 SP1 and later includes a similar iterator function arcpy.da.walk, which can navigate both folder and geodatabase workspaces (not just file system folders as os.walk does).

View solution in original post

1 Reply
curtvprice
MVP Esteemed Contributor

Here's a revised script for you.

import os
import fnmatch
import arcpy
rootPath = r"C:\Project\layers" 
pattern = 'mig*.shp' 
for root, dirs, files in os.walk(rootPath): 
    for filename in fnmatch.filter(files, pattern): 
        shp = os.path.join(root, filename)
        if arcpy.ListFields(shp, "YEUD"):
            print("{} has YEUD field".format(shp)) 
            with arcpy.da.SearchCursor(shp, ["YEUD"]) as rows:
                for row in rows:
                    if row[0] == 20:
                        print("{} has a record with YEUD = 20".format(shp))
                        break

A few notes:

  • Line 1: I'm adopting the Python convention (PEP-8) of putting imports on their own line (easier to edit out modules you don't need that way).
  • Line 9: You were running arcpy.ListFields on a folder at the beginning. You need to run it on a dataset, inside the loop.
  • Line 9: The approach I normally use to test for field existence is to call arcpy.ListFields(tbl, field_name), if it comes back as an empty list  [], this means the field was not there. An empty list is interpreted as False when used in an if statement.
  • Line 11: The cursor is run here on the shape file table, not rootPath.
  • Line 15: Once I find a row with YEUD = 20, I jump out of the loop so I don't report more than once if there are multiple rows with that value.
  • ArcGIS 10.1 SP1 and later includes a similar iterator function arcpy.da.walk, which can navigate both folder and geodatabase workspaces (not just file system folders as os.walk does).