0

I am trying to get my script to loop through a folder of shapefiles and a folder of gdbs. I need it to compare the name of the shapefiles and gdbs and if they match to continue on to loop through the dataset then feature class of the gdb.

Currently I am trying to set the environment to the current gdb the loop is on as shown in line 29. This gives me the error: 'NoneType' object is not iterable... referring to line 34, "for ds in datasets:"

If I hard code the environment to a gdb folder path instead to test it out, the the script runs but skips over lines 34 to 37.

import arcpy
import os

arcpy.env.overwriteOutput = True

directoryPath = r"C:\Test\ShapefileAOI"
workspace = r"C:\Test\Geodatabase"


for path, dirc, files in os.walk(directoryPath):
    for aoi in dirc:
        split = os.path.splitext(aoi)
        #print(split)
        firstSplit = os.path.splitext(aoi)[0]
        #print('AOI ' + firstSplit)   

        for path, dirs, files in os.walk(workspace):
            for d in dirs:
                splitGdb = os.path.splitext(d)
                firstSplitGdb = os.path.splitext(d)[0]
                #print('gdb ' + firstSplitGdb)
                environment = d
                
                if firstSplitGdb == firstSplit:
                    print (firstSplitGdb + " shapefile matches " + firstSplit + " gdb")
                    
                    # set the workspace to the gdb path 
                    arcpy.env.workspace = environment 
                    
                    
                    datasets = arcpy.ListDatasets(feature_type='feature')

                    for ds in datasets:
                        for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
                            path = os.path.join(arcpy.env.workspace, ds, fc)
                            print(path)
                
                else:
                    print(firstSplitGdb + " shapefile does NOT match " + firstSplit + " gdb")
3
  • 1
    It's not required that a file geodatabase have any feature datasets. You need to test if datasets: before iterating.
    – Vince
    Dec 20, 2021 at 21:22
  • Do you have any subdirectories or are all the files located within a single directory for each type of file?
    – Aaron
    Dec 20, 2021 at 21:44
  • They are located in a single directory for each file type.
    – Mackenzie
    Dec 21, 2021 at 15:48

1 Answer 1

2

If I understand what you are trying to do, I believe the code at the bottom of my response will work.

Before getting to my code, some comments on your code...

Unless your datasets and folder contents are changing very frequently, as in faster than it takes for the script to run, having nested os.walk statements is inefficient. Instead, it is better to inventory all your shape files and file geodatabases in single passes and then compare the inventories to find common names.

For listing geospatial data, I suggest using ArcPy Data Access module Walk function rather than the older List functions. Not only is arcpy.da.Walk more Pythonic, it is quite common for users to get tripped up setting workspaces with the older List functions.

Although it may not be the case with your data, it is good to remember that Python is case sensitive in its string comparisons ( "THIS_FILE.SHP" != "this_file.shp" ). Your original code was assuming the case would match along with names.

# following assumes Python 3 (ArcGIS Pro instead of ArcMap)
import arcpy
import os

# set paths
shp_root = r"C:\Test\ShapefileAOI"
gdb_root = r"C:\Test\Geodatabase"

# inventory shape files and file geodatabases
shp_files = {
    os.path.splitext(f)[0].upper(): os.path.join(root, f)
    for root, dirs, files in os.walk(shp_root)
    for f in files
    if os.path.splitext(f)[1].upper() == ".SHP"
}
gdb_folders = {
    os.path.splitext(d)[0].upper(): os.path.join(root, d)
    for root, dirs, files in os.walk(gdb_root)
    for d in dirs
    if os.path.splitext(d)[1].upper() == '.GDB'
}

# list feature classes in file geodatabases that have GDB name
# in common with a shape file name
common_names = shp_files.keys() & gdb_folders.keys()
for name in common_names:
    print(*(
        os.path.join(root, f)
        for root, dirs, files in arcpy.da.Walk(gdb_folders[name], datatype='FeatureClass')
        for f in files
        ),   
        sep='\n'
    )

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.