I'm looking for a way to generate one complete list of all feature classes within all feature datasets inside a gdb.
If I execute the script below, it generates multiple lists of feature classes for each dataset within the gdb. Is there a way to combine each of these separate lists of feature classes into one complete list?
import arcpy gdb = r"...path to some gdb" arcpy.env.workspace = gdb dsList = arcpy.ListDatasets("*", feature_type="Feature") dsList.sort() for ds in dsList: print ds ...list of datasets... for ds in dsList: fcList = arcpy.ListFeatureClasses("*", feature_type="ALL", feature_dataset=ds) fcList.sort() print fcList ...separate lists of feature classes per feature dataset...
Thanks in advance!
Solved! Go to Solution.
Hi Matthew,
Try the following:
fcList = [] for dataset in arcpy.ListDatasets(): for fc in arcpy.ListFeatureClasses("*", "ALL", dataset): fcList.append(fc) for fc in arcpy.ListFeatureClasses(): fcList.append(fc) print fcList
Hi Matthew,
Try the following:
fcList = [] for dataset in arcpy.ListDatasets(): for fc in arcpy.ListFeatureClasses("*", "ALL", dataset): fcList.append(fc) for fc in arcpy.ListFeatureClasses(): fcList.append(fc) print fcList
Thanks Jake Skinner. That works!
The second code sample in the ArcGIS Help 10.2 - ListFeatureClasses (arcpy) gets you most of the way there. The code below is adapted from the second code example:
import arcpy import os gdb = # arcpy.env.workspace = gdb datasets = arcpy.ListDatasets(feature_type='feature') datasets = [''] + datasets if datasets is not None else [] fcList = [] for ds in datasets: for fc in arcpy.ListFeatureClasses(feature_dataset=ds): fcList.append(os.path.join(gdb, ds, fc)) # fcList.append(os.path.join(ds, fc)) # if you don't want gdb path included fcList.sort()
The Esri sample code, beyond providing the functional framework, incorporated two notable tips/ideas/practices. The first is that including an empty string '' in the datasets list will allow the datasets loop to include the feature classes that aren't in a data set, i.e., the feature classes that are in the root/base of the geodatabase.
The second is that os.path.join is used to create the full path of the feature classes being listed. If you are going to do any further processing of the list of feature classes, having the full path to them in the list makes the next steps easier. Even if you are just listing feature classes to know what is present, including the data set along with the feature class will provide for more context.
Having a bit of a unique problem with this code. I used a bit of the code above to nest the ListFeatureClasses inside of the ListDatasets. Under my ListFeatureClasses section I'm trying to use arcpy.Describe to extract the geometry storage type of the feature class. I've hit a wall where if the feature class and the feature dataset have the exact same name my second for statement is closing out.
import os, arcpy, time from time import clock, strftime, localtime try: sdeConn = "Database Connections\\washsde_rlis_sde.sde" arcpy.env.workspace = sdeConn oFileHeaders = "FeatureDataset,FeatureClass,Geometry" oListTime = time.asctime() f = open("K:/Workgroups/GISITS/ADMIN_DBA_Projects/Binary2SQLGeometry/WashSDE_RLIS_fcGeom.csv", "w") f.write("SDE Connection: " + sdeConn + "\n") f.write("List Created On: " + oListTime + "\n") datasets = arcpy.ListDatasets(feature_type='feature') datasets = [''] + datasets if datasets is not None else [] print datasets f.write('Datasets in geodatabase: ' + str(datasets) + "\n") f.write(oFileHeaders + "\n") for ds in datasets: for fc in arcpy.ListFeatureClasses(feature_dataset=ds): desc = arcpy.Describe(fc) vFile = desc.file vPath = desc.path vGeometry = desc.geometryStorage f.write(ds + "," + vFile + "," + vGeometry + "\n") print (ds + "," + vFile + "," + vGeometry) f.close() except: print arcpy.GetMessage(1) print arcpy.GetMessage(arcpy.GetMessageCount() - 1)
I get a type 1 exception when its trying to deal with the RLIS.RLIS.boundary feature class in the similarly named RLIS.RLIS.BOUNDARY feature dataset. The SDE instances is named RLIS and the database users is named RLIS.
I find the original listing data functions (ListDatasets, ListFeatureClasses, ListFiles, etc...) rather clunky to work with compared to other options. The ArcPy Walk function is good for finding or enumerating data sets. In this case, though, since you are focused on specific geodatabases and want additional properties of data sets, like geometry storage type, I think the old Describe class is best.
The code below will go through a geodatabase and print out the data set names, types, and geometry storage if applicable.
import os
gdb = # path to geodatabase
full_path = False # Specify whether dataset name should be full or relative
desc = arcpy.Describe(gdb)
for child in desc.children:
datasets = [child] + child.children
for ds in datasets:
print "{},{},{}".format(
ds.catalogPath.replace("" if full_path else gdb + os.path.sep, ""),
ds.datatype,
ds.geometryStorage if hasattr(ds, "geometryStorage") else ""
)