2

I am using QGIS 3.10.2-A Coruña and its Python Console. Currently I am modifying features and attributes of a shape file, e.g. dropping features:

caps = layer.dataProvider().capabilities()
if caps & QgsVectorDataProvider.DeleteFeatures:
    res = layer.dataProvider().deleteFeatures(selId)

where selId are the features to be dropped.

I noticed that when I do such operations changes are immediately saved to the file that is stored on my hard disk, which sort of eliminates the advantage of using a script in the first place.

What do I need to do to get around changes being saved automatically? I read about "editing buffers" in the QGIS Developer Cookbook but I am unsure whether that's what I need.

EDIT:

Just noticed that the layer is only saved on the hard disk (overwrites the current file) if executing the code results in actual changes in the layer. Running the code below for a second time doesn't delete any additional features bc selId doesn't change and the layer is NOT saved again. The same applies to the code proposed in the answer below. It seems like the automatic saving isn't triggered by the code itself but maybe rather by some general preference setting according which any changes to a layer are automatically saved to the hard disk? Does sth like that exist?

2

I think if you don't use dataProvider it's ok. Found in Deleting selected features using PyQGIS?:

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())
2
  • Unfortunately, changes are still saved immediately. – L B Mar 20 '20 at 9:44
  • Are you sure your underlying file is not updated at the end of the "edit" session ? Can you try with 'layer.startEditing()' and 'layer.commitChanges()' instead of 'with edit(layer)'? – etrimaille Mar 20 '20 at 10:03
0

Solution based on previous answers:

Indeed using 'layer.startEditing()' and 'layer.commitChanges()' does not save the changes to the file on the disk. This looks like this:

# start editing
layer.startEditing()
# check editing mode
layer.isEditable()

layer.beginEditCommand("Delete features")

# filter features
request = QgsFeatureRequest().setFilterExpression('"field" = \'val\'')

# attributes & geometry: none
request.setSubsetOfAttributes([])
request.setFlags(QgsFeatureRequest.NoGeometry)

# loop over features & deleteAllCategories
for f in layer.getFeatures(request):
    layer.deleteFeature(f.id())

However, based on the PyQGIS cookbook I thought it should be equivalen to what was proposed by @Cupain. Could somebody explain the difference and when one or the other is better?

Also why/when are the commands 'layer.beginEditCommand()' and 'layer.endEditCommand()' needed? In the PyGQIS cookbook these are used tgth with 'layer.startEditing()' and 'layer.commitChanges()'.

3
  • There isn't endEditCommand and commitChanges in your snippet? – etrimaille Mar 24 '20 at 10:05
  • You are asking two questions in the area reserved for answers to the original question. – PolyGeo Mar 24 '20 at 10:24
  • @etrimaille: the thing is that if I add layer.commitChanges() to the above code all changes are directly saved to the file on the disk again (same result as with "with edit(layer)"). So if I don't want to save the changes on the hd I just don't use commit.changes()? – L B Mar 24 '20 at 17:30

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.