PyQGIS 3 – How to Check if a Field Exists in a Layer Using Python?

pyqgispyqgis-3

There are a few posts similar to this one, but none that I have found that hit it right on the head. My question is simply, how can you find if a field exists in a layer in QGIS 3.0.2 using Python?

From my understanding, layers have features. Each feature has fields. If you add a SHP file to your Layers window, then right click and select Open Attribute Table, you can view these features and their fields for the given layer.

When looking at the Attribute Table, you can see that it is just that, a table of rows and columns. From everything I can see, each row is a feature and each column is a field. Furthermore, all features share the same fields.

With that said, it is also true that fields can be dynamic for each layer. Meaning all layers do not need to share the same fields. However, in a given layer, all features do share all fields.

So, here inlays my question. The QGIS 3.0.2 API allows you to do the following to get the layers

layers = self.iface.mapCanvas().layers()

This is all well. It would seem, given the rules I described above, that you would now have a table of features and their fields. This table has many different features, but all of these features share the same fields. So you would think there would be a way to get the table meta data, which would contain the field names. Instead, the only thing I have found is to get a list of features and then get a list of one of the feature's fields, as follows.

found = false
for feature in layer.getFeatures():
    try:
        feature.attribute("fieldName") # Throws exception if it does not exist
        found = true
    except KeyError as e:
        # all features have hte same fields, so if it doesn't exists in the first feature, it won't exist in the others
        break
    finally:
        # all features have the same fields, so only need to check the first
        break

Is there no way to just check the field names of a layer's attribute table?

Best Answer

Welcome to GIS.SE!

As you thought, there is a way to know if a field exists in a layer not by iterating features but by looking at the layer structure.

In the QGIS Layers Panel, select a layer.

Then in the Python Console inside QGIS, run the following code:

field_name = "my_field"
layer = iface.activeLayer() # Gives you the layer you have selected in the Layers Panel

field_index = layer.fields().indexFromName(field_name)

if field_index == -1:
    print("The field {} does not exist in layer {}!".format(field_name, layer.name()))
else: 
    print("The field {} exists in layer {}!".format(field_name, layer.name()))

As you can see, we access the fields of the layer by calling layer.fields(), which gives us a QgsFields object. If you look at the docs, the method indexFromName() from QgsFields gives us the index of a field in the field set. If such index is -1, it means the field couldn't be found.


Note: You could also use layer.fields().indexOf(field_name) to do the check.

Related Question