How to remove or delete column fields in a shapefile using PyQGIS?
Best Answer
If you get no joy with QGSVectorLayer::deleteAttribute as they docs say: delete an attribute field (but does not commit it) have a look at the data provider. As QGIS deals with lots of feature types with different drivers I suspect that it's left up to the driver as to whether or not a field can be deleted.
Here's some code that I dredged up that may help:
fields = vlayer.dataProvider().fields()
count = 0
for name, field in fields.iteritems():
if field.name() == fieldName:
return count
count += 1
To get the index of the field from the name. In this case I'm not using .upper() but I would recommend it.
After getting the index of the field you (might) delete it using the dataprovider.
You can loop over the iterator and get the id() for every feature in it:
with edit(layer):
# build a request to filter the features based on an attribute
request = QgsFeatureRequest().setFilterExpression('"DN" != 3')
# we don't need attributes or geometry, skip them to minimize overhead.
# these lines are not strictly required but improve performance
request.setSubsetOfAttributes([])
request.setFlags(QgsFeatureRequest.NoGeometry)
# loop over the features and delete
for f in layer.getFeatures(request):
layer.deleteFeature(f.id())
or with QGIS < 2.12
request = QgsFeatureRequest().setFilterExpression('"DN" != 3')
request.setSubsetOfAttributes([])
request.setFlags(QgsFeatureRequest.NoGeometry)
ids = [f.id() for f in layer.getFeatures(request)]
layer.startEditing()
for fid in ids:
layer.deleteFeature(fid)
layer.commitChanges()
Best Answer
If you get no joy with QGSVectorLayer::deleteAttribute as they docs say: delete an attribute field (but does not commit it) have a look at the data provider. As QGIS deals with lots of feature types with different drivers I suspect that it's left up to the driver as to whether or not a field can be deleted.
Here's some code that I dredged up that may help:
To get the index of the field from the name. In this case I'm not using
.upper()
but I would recommend it.After getting the index of the field you (might) delete it using the dataprovider.
It's expecting a list so the integer needs to be put into a list. I have not used this method; normally I would use ArcMap to delete the field.
As pointed out by RogerHuang, the fields of the layer may need to be updated now that they have been changed to refresh the layers' fields definition: