1

Suppose I have a geodatabase in C:/MyDir/MyGDB.gdb. I am working outside of the Esri/ArcPy environment, primarily using gdal and os libraries. I want to retrieve and verify the file path of a feature class inside my gdb. The feature class, 'my_feature', is in a feature dataset called 'my_dataset'. I have tried:

 import os
 import gdal

 my_path = r"C:\MyDir\MyGDB.gdb\my_dataset\my_feature"
 os.path.exists(my_path)
 >>> False

How can I verify the file path for my feature class using GDAL with Python (and without using ArcPy)?

2 Answers 2

3

File geodatabase uses the database trick of using a catalog table to store contents. It's much the same as the enterprise geodatabase technique. That means that files under the .gdb folder do not have distinguishable names (unless you know the creation order of tables (and feature datasets are a property in a lookup table, not a subfolder).

That means that Python file system access tools are useless for this task. The only Esri documentation on the implementation is manifested in the File Geodatabase API, so the best way to know anything about what's under the .gdb older is via the FGDB API DLL.

There is a open-source reverse-engineered copy of the FGDBAPI (OpenFileGDB). It's read-only and doesn't support rasters or compressed GDBs, though it does support 9.x geodatabases (which Esri's freely licensed DLL doesn't support, and even Esri's DLL don't support FGDB rasters), but from Python you have your choice of tools which use one of those two DLLs, or writing your own from scratch (I could do it, technically, but wouldn't because I've written enough binary readers to know what a PITA it would be).

So your answer is likely to either use a GDAL binary in a subprocess, or use GDAL's Python bindings. If the question is really, "How can I do this without any 3rd party code?" then you have a long couple of weeks/months ahead of you.

2
2

You could just try opening the dataset/layer. Note that you don't need to tell GDAL about the GDB FeatureDataset.

If you want to actually roll your own exists function, you could do something like the following, but note that you will be opening the dataset twice, once when checking and again when opening for real. Which is not negligible when the dataset/layer is remote (i.e a URL) or in a zip file. Also note that this example doesn't handle GDAL raster subdatasets, but could fairly easily.

from osgeo import gdal

gdal.UseExceptions()

def exists(datasource, layer=None):
    try:
        ds = gdal.OpenEx(datasource)
        if layer is not None:
            return ds.GetLayerByName(layer) is not None
        else:
            return True

    except RuntimeError as e:
        return False


print(exists("exists.gdb", "existing_fc"))
print(exists("doesnt_exist.gdb", "no_such_fc"))
print(exists("exists.gdb", "no_such_fc"))
print(exists("exists.tif"))
print(exists("no_such.tif"))

Output:

True
False
False
True
False

If you do want to test the feature dataset part, you could do something like:

def exists(datasource, featuredataset=None, layer=None):
    try:
        ds = gdal.OpenEx(datasource)

        if featuredataset is not None:
            rg = ds.GetRootGroup()
            fd = rg.OpenGroup(featuredataset)
            if fd is not None:
                if layer is not None:  # Testing existence of layer inside featuredataset
                    return fd.OpenVectorLayer(layer) is not None
                else:
                    return True  # Testing existence of featuredataset

        if layer is not None: # Testing existence of layer
            return ds.GetLayerByName(layer) is not None
        else:
            return True # Testing existence of datasource

    except RuntimeError as e:
        return False


print(exists("exists.gdb", "existing_fd", "existing_fc"))

Output:

True  # Note exists("exists.gdb", "existing_fc") will also return True even if it's in a feature dataset
2
  • I like this solution and even tried to use ds.GetDescription() which will return the filepath of the parent gdb but only returns the name at the layer level. The one flaw of this method is that I really want the filepath of the feature class (inside the dataset, if that's the case) . I know "C:\MyDir\MyGDB.gdb\my_dataset\my_feature" exists but I need that returned or verified specifically.
    – gwydion93
    Oct 21, 2022 at 12:23
  • @gwydion93 see edit
    – user2856
    Oct 21, 2022 at 20:29

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.