5

I have a project folder with many many folders within that. Some of these child folders contain a Esri .gdb file geodatabase. I want to list all the feature classes that are inside the GDBs that have AOI (Area of Interest) as a prefix.

I've tried the following:

import sys
from pathlib import Path
import arcpy

# -------------- FUNCTIONS --------------------
def searching_all_files(directory):
    file_list = []
    for x in directory.iterdir():
        if x.is_dir():
            if (x.suffix == '.gdb'):
                arcpy.env.workspace = str(x)
                for f in arcpy.ListFeatureClasses( "AOI*" , "Polygon" ):
                    file_list.append(f)
            else:
               file_list.extend(searching_all_files(x))
    return file_list

# -------------- INIT --------------------
folder_path = r'C:\Projects'
folder_path = Path(folder_path)

list_of_files = searching_all_files(folder_path)
print(list_of_files)

This code is not listing the features, after many trials, I couldn't figure out what I've missed. Could someone give a hint how to reach that?

3
3

I'm not sure exactly where your script is running off the rails, but I did notice a few things. Your fist elif on line 9 should probably be just an if. and it is giving me an illegal target error. Second, in the else statement on line 15 you are tacking on function calls to your file list which i'm not sure you want.

Try this. os.walk is a beautiful little function that walks through a directory returning all found paths, directories and files. It takes care of a lot of the path and search nonsense for you.

https://docs.python.org/3/library/os.html#os.walk

import os
import arcpy

search_directory = r'C:\Projects'

# small function to walk through directory and check all .gdbs in a folder.
def directory_walk(directory_to_search):
    for path, dirs, files in os.walk(directory_to_search):
        for dir in dirs:
            if dir.lower().endswith(".gdb"):
                # Generator magic, pops off one record at a time.
                yield os.path.join(path, dir)



feature_list = []
for gdb in directory_walk(search_directory):
    arcpy.env.workspace = gdb
    fc = arcpy.ListFeatureClasses("AOI*", "Polygon")
    feature_list.extend(fc)  # add found Feature classes to file list

print(feature_list)

If you wanted the file paths instead you could loop through the feature list and append the path returned from os.walk to get paths like so

import os
import arcpy

search_directory = r'C:\Projects'

# small function to walk through directory and check all .gdbs in a folder.
def directory_walk(directory_to_search):
    for path, dirs, files in os.walk(directory_to_search):
        for dir in dirs:
            if dir.lower().endswith(".gdb"):
                # Generator magic, pops off one record at a time.
                yield os.path.join(path, dir)



feature_list = []
for gdb in directory_walk(search_directory):
    arcpy.env.workspace = gdb
    fc = arcpy.ListFeatureClasses("AOI*", "Polygon")
    for f in fc:
        feature_list.append(os.path.join(gdb, f))

print(feature_list)

os.path.join takes care of all the mess of dealing with // and \ and what nots as well.

1
  • Ohh... I added my code to insert in here and I forgot to change the "elif" to "if". But in my code it's alright. It's so strange because the first code script you presented worked for me. The second one, that has the same approach I was taking, didn't work here. Anyways, thank you so much for your answer. It clarified me a lot in the direction I can follow for this and next projects!! Best to you! – MapsEveryWhere Sep 3 '20 at 13:54
2

You can easily access geodatabases and featureclasses with fiona and glob using a couple lines of code. In this example, glob is used to list all of the geodatabases in a directory dir. fiona.listlayers() is used within in a list comprehension to iterate through all the featureclasses in each geodatabase with the "AOI" condition. Finally, itertools flattens the list so that all of the featureclasses are in a single list.

import fiona
import os, itertools, glob

dir = '/path/to/your/directory'

# List all GDB's recursively
gdbs = glob.glob(os.path.join(dir, '**/*.gdb'), recursive = True)

# List all featureclasses in each GDB IF 'AOI' is in the featureclass name
fcs = list(itertools.chain.from_iterable([[os.path.join(y,x) for x in fiona.listlayers(y) if 'AOI'.lower() in x.lower()] for y in gdbs]))

This will produce a list of featureclasses with "AOI" anywhere in the featureclass name, for example:

['/dir1/geodatabase1.gdb/Aoi1',
 '/dir1/geodatabase1.gdb/AOI2',
 '/dir1/dir2/geodatabase2.gdb/xyz_AoI',
 '/dir3/dir4/dir5/geodatabase6.gdb/another_one_aoi_xyz']
2
  • 1
    Amazing!!! Great option to use. In this way, how could I get featureclasses that has same name with different cases ("AOI", "aoi", "Aoi")? – MapsEveryWhere Sep 4 '20 at 17:47
  • I believe you can use the .lower() method. For example, change if 'AOI' in x to if 'AOI'.lower() in x.lower(). I edited the answer to with this method to address case. – Aaron Sep 4 '20 at 18:10

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.