2

I have a vector layer with 50 columns/fields. I have been trying to find a way of selecting 6 columns of particular interest (by name or index) and then creating a new layer from that selection, such that my new layer only has those 6 columns within it. I am hoping to achieve this with PyQGIS

At present, the only way I've solved this is to create a copy of the layer and then, following the documentation, delete attributes I don't want to keep from that copied layer. Seems very clunky. I would prefer a method that does this by selection rather than deletion


caps = layer.dataProvider().capabilities()
if caps & QgsVectorDataProvider.DeleteAttributes:
    res = layer.dataProvider().deleteAttributes([43,42])
    layer.updateFields()

Is there a more elegant way of doing this?

2

You can use the code below. Just modify the field_list object to contain the names of the 6 fields you want to copy, select your source layer as the active layer and run the code.

# Place the names the of the 6 fields you want to keep in the list below
field_list = ['Field_Name_1',
              'Field_Name_2',
              'Field_Name_3',
              'Field_Name_4',
              'Field_Name_5',
              'Field_Name_6']

# select the layer you want to copy
src_layer = iface.activeLayer()

geom_type = QgsWkbTypes.displayString(src_layer.wkbType())
src_crs = src_layer.crs().authid().split(':')[1]
uri = '{}?epsg:{}'.format(geom_type, src_crs)
res_layer = QgsVectorLayer(uri, 'Result', 'memory')
res_layer.dataProvider().addAttributes([f for f in src_layer.fields() if f.name() in field_list])
res_layer.updateFields()
with edit(res_layer):
    for feat in src_layer.getFeatures():
        atts = {}
        for i in field_list:
            atts[res_layer.fields().lookupField(i)] = feat.attribute(src_layer.fields().lookupField(i))
        res_feat = QgsFeature()
        res_feat.setGeometry(feat.geometry())
        res_layer.dataProvider().addFeature(res_feat)
        res_layer.dataProvider().changeAttributeValues({res_feat.id(): atts})

QgsProject().instance().addMapLayer(res_layer)
| improve this answer | |
  • Thanks @Ben W This works really well. I am getting a layer added to the table of contents of my map as desired with the specified columns. Strangely though I am not seeing the layer displayed in the display window – TrevP Oct 25 at 15:37
  • I discovered the reason why @Ben W code above wasn't giving me a feature layer display in the QGIS map window. One very small typo in this line -- uri = '{}?crs=epsg:{}'.format(geom_type, src_crs) --- added in crs= Couldn't edit in code above as too short to be accepted – TrevP Oct 27 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.