ESRI has provided a tool that generates a file database description.
The description itself is extremely useful and we will look at it in more detail in one of the following posts. Now, we'll use it to answer our questions.
The tool is called Generate Excel From Geodatabase.
We attach a link to help
In the Excel table generated by this tool, descriptions of classes and their fields, as well as a set of additional information, are available.
Since an additional license is required, which in my case is not available, we will have to make our own tool that returns the necessary information.
Let's start at the first step, we will create a new notebook. This is done by selecting the Analysis tab from the Python button.
We will use the arcpy.ListFields function from the ESRI library. In the window we add the following code. Which returns all the fields of a particular feature class.
import arcpy
featureclass = r"C:\GISProject\GISBlog\Tools_Projects\MD_add_fields\AddFields.gdb\ne_10m_admin_0_map_units"
field_names = [f.name for f in arcpy.ListFields(featureclass)]
print(field_names)
The result of our code is a list of fields
['OBJECTID', 'Shape', 'scalerank', 'featurecla', 'Shape_Length', 'Shape_Area', 'Name_EN']
in this list.
The output fields are only for one feature class and that is the „ne_10m_admin_0_map_units“ class.
Now we need a list of all feature classes.
For this purpose, we will use arcpy‘s ListFeatureClasses function in the following code.
import arcpy
import os
arcpy.env.workspace = r“..\AddFields.gdb“
datasets = arcpy.ListDatasets(feature_type=‘feature‘)
datasets = [‚‘] + datasets if datasets is not None else []
for ds in datasets:
for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
path = os.path.join(arcpy.env.workspace, ds, fc)
print(path)
We‘ve flagged the code from the previous step to not run. The output of this code is to print a list of all the classpaths available in the database. ..\AddFields.gdb\ne_10m_admin_0_antarctic_claim_limit_lines ..\AddFields.gdb\ne_10m_admin_0_antarctic_claims ..\AddFields.gdb\ne_10m_admin_0_boundary_lines_disputed_areas ..\AddFields.gdb\ne_10m_admin_0_boundary_lines_land ..\AddFields.gdb\ne_10m_admin_0_boundary_lines_map_units ..\AddFields.gdb\ne_10m_admin_0_boundary_lines_maritime_indicator ..\AddFields.gdb\ne_10m_admin_0_countries
Now we need to merge the two pieces of code, the part that reads the fields in a class and the part that reads all available classes from GDB.
This is done by using the output from the ListFeatureClasses traversal of feature class names and making it input to ListFields.
import arcpy
import os
arcpy.env.workspace = r“..\AddFields.gdb“
datasets = arcpy.ListDatasets(feature_type=‘feature‘)
datasets = [‚‘] + datasets if datasets is not None else []
for ds in datasets:
for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
path = os.path.join(arcpy.env.workspace, ds, fc)
print(path)
field_names = [f.name for f in arcpy.ListFields(path)]
print(field_names)
Let‘s see the result.
As you can see this list returns all the fields but we are looking for a specific field by name. The question remains, how to display only feature classes in which the field "Name_EN.
For this purpose, we will add a check.
If search_feeld_name in field_names:
This check, we will combine it with the rest of the functions. We will also add an explanatory text for the name of the field we are looking for as well as the class in which it is located.
import arcpy
import os
search_feeld_name = 'Name_EN'
arcpy.env.workspace = r"..AddFields.gdb"
datasets = arcpy.ListDatasets(feature_type='feature')
datasets = [''] + datasets if datasets is not None else []
for ds in datasets:
for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
path = os.path.join(arcpy.env.workspace, ds, fc)
# print(path)
field_names = [f.name for f in arcpy.ListFields(path)]
# print(field_names)
if search_feeld_name in field_names:
print(f"field {search_feeld_name} exist in feature class: {path}")
If we want to check the classes in which a field is missing, then this is quite easy.
import arcpy
import os
search_feeld_name = 'Name_EN'
arcpy.env.workspace = r"..\AddFields.gdb"
datasets = arcpy.ListDatasets(feature_type='feature')
datasets = [''] + datasets if datasets is not None else []
for ds in datasets:
for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
path = os.path.join(arcpy.env.workspace, ds, fc)
# print(path)
field_names = [f.name for f in arcpy.ListFields(path)]
# print(field_names)
if search_feeld_name in field_names:
# print(f"field {search_feeld_name} exist in feature class: {path}")
pass
else:
print(f"field {search_feeld_name} don't exist in feature class: {path}")
If we want to save this information in an additional file, we can do so. We use the built-in functionality in python f.write, where f is a parameter for the file path and the reading mode in which it is used.
This is all the code we created.
import arcpy
import os
search_feeld_name = 'Name_EN'
f = open(r"C:\GISProject\GISBlog\checkfieldname.txt", "a")
arcpy.env.workspace = r"..\AddFields.gdb"
datasets = arcpy.ListDatasets(feature_type='feature')
datasets = [''] + datasets if datasets is not None else []
for ds in datasets:
for fc in arcpy.ListFeatureClasses(feature_dataset=ds):
path = os.path.join(arcpy.env.workspace, ds, fc)
# print(path)
field_names = [f.name for f in arcpy.ListFields(path)]
# print(field_names)
if search_feeld_name in field_names:
# print(f"field {search_feeld_name} exist in feature class: {path}")
pass
else:
print(f"field {search_feeld_name} don't exist in feature class: {path}")
f.write(f"field {search_feeld_name} don't exist in feature class: {path}")
f.write("\n")
f.close()
Here is what the text file we created contains, or is it a list of all layers in which our field is not present.
If we want to display a list of all layers in which the field is available, we must use it:
if search_feeld_name in field_names:
Let‘s do it by setting a new file name.
Let's review the result file, as these are all feature classes in which the field with the given name is present.
That's what this post is for in the future, we'll look at how we can build on this functionality and use it in custom tools.
Thanks for your attention, for more posts subscribe to our newsletter.