7

I have a PyQGIS script which carries out a number of operations on layers and writes the results to shapefiles. However, I understand that GeoPackages have a number of advantages (not having multiple files being an obvious one) and would like to change to use them. However, I am having trouble writing to them.

Using QgsVectorFileWriter.writeAsVectorFormat I was able to write to a GeoPackage. Once. But on calling the script again I get an error:

"a file system object (file name} already exists".

Fair enough: I added the option QgsVectorFileWriter.CreateOrOverwriteFile. But this has no effect - I get the same error message.

If I use option QgsVectorFileWriter.CreateOrOverwriteLayer then I can overwrite an existing file, but cannot create the file in the first place: it produces an error:

'Opening of data source in update mode failed'.

I have tried both writeAsVectorFormat and writeAsVectorFormatV2 but can get neither to work.

This is with QGIS 3.10.

Why does CreateOrOverwriteFile not cause the file to be overwritten? How does one code this so that it works both on the first and the subsequent times that the script is used?

transform_context = QgsProject.instance().transformContext()
save_options = QgsVectorFileWriter.SaveVectorOptions()
#save_options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteFile
save_options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
#err = QgsVectorFileWriter.writeAsVectorFormat(layer, gpkgFilePath, save_options) 
err = QgsVectorFileWriter.writeAsVectorFormatV2(layer, gpkgFilePath, transform_context, save_options)  

With regards to the first part of my question: it turns out to be a combination of a timing issue and an erroneous error message. Apparently, when you remove a Shape layer QGIS closes the file immediately, but when you remove a Geopackage layer it only does so later (even if it is the only layer in the file). If one then tries to overwrite the file it should produce a "file is open" message, but instead says "file already exists" (which is true but irrelevant).

As far as getting it to work is concerned, it works if I do this:

transform_context = QgsProject.instance().transformContext()
save_options = QgsVectorFileWriter.SaveVectorOptions()
save_options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
err = QgsVectorFileWriter.writeAsVectorFormatV2(layer, gpkgFilePath, transform_context, save_options)

if err:
    if err[0] == QgsVectorFileWriter.ErrCreateDataSource: 
        show('-- does not exist; creating file: ' + gpkgFilePath)
        save_options = QgsVectorFileWriter.SaveVectorOptions()
        err = QgsVectorFileWriter.writeAsVectorFormatV2(layer, gpkgFilePath, transform_context, save_options)

        if err and err[0]!=0:  
            show("Error creating file with layer " + layerName + " " + str(err))
            return

    elif err[0]!=0:
        show("Error writing layer " + layerName + " " + str(err))
        return 

Though that is awfully clunky - it's an answer, but not a terribly good one. Is there no way of doing this with a single write?

2
  • 1
    Can you add a bit more code please. Make it a runnable example so we just have to edit to specify our own file/layer to test with.
    – user2856
    Commented Aug 8, 2020 at 6:59
  • I just had an idea. A bit more experimenting suggests that the error message QGIS is giving me is itself erroneous. I will experiment further, and provide a minimal working example if I can't fix it. Commented Aug 8, 2020 at 8:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.