vectorappendwritergeopackagepyqgis

How to append / add layers to geopackages in PyQGIS


For a project I am creating different layers which should all be written into one geopackage. I am using QGIS 3.16.1 and the Python console inside QGIS which runs on Python 3.7

I tried many things but cannot figure out how to do this. This is what I used so far.

vl = QgsVectorLayer("Point", "points1", "memory")
vl2 = QgsVectorLayer("Point", "points2", "memory")

pr = vl.dataProvider()
pr.addAttributes([QgsField("DayID", QVariant.Int), QgsField("distance", QVariant.Double)])
vl.updateFields()

f = QgsFeature()
for x in range(len(tag_temp)):
    f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(lon[x],lat[x])))
    f.setAttributes([dayID[x], distance[x]])
    pr.addFeature(f)
vl.updateExtents()

# I'll do the same for vl2 but with other data

uri ="D:/Documents/QGIS/test.gpkg"
options = QgsVectorFileWriter.SaveVectorOptions()
context = QgsProject.instance().transformContext()
QgsVectorFileWriter.writeAsVectorFormatV2(vl1,uri,context,options)
QgsVectorFileWriter.writeAsVectorFormatV2(vl2,uri,context,options)

Problem is that the in the 'test.gpkg' a layer is created called 'test' and not 'points1' or 'points2'. And the second QgsVectorFileWriter.writeAsVectorFormatV2() also overwrites the output of the first one instead of appending the layer into the existing geopackage.

I also tried to create single .geopackages and then use 'Package Layers' processing tool (processing.run("native:package") to merge all layers into one geopackage, but then the attributes types are all converted into strings unfortunately.

Any help is much appreciated. Many thanks in advance.


Solution

  • You need to change the SaveVectorOptions, in particular the mode of actionOnExistingFile after creating the gpkg file :

    options = QgsVectorFileWriter.SaveVectorOptions()
    #options.driverName = "GPKG" 
    
    options.layerName = v1.name()
    QgsVectorFileWriter.writeAsVectorFormatV2(v1,uri,context,options)
    #switch mode to append layer instead of overwriting the file
    options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
    options.layerName = v2.name()
    QgsVectorFileWriter.writeAsVectorFormatV2(v2,uri,context,options)
    

    The documentation is here : SaveVectorOptions

    I also tried to create single .geopackages and then use 'Package Layers' processing tool (processing.run("native:package") to merge all layers into one geopackage, but then the attributes types are all converted into strings unfortunately.

    This is definitively the recommended way, please consider reporting the bug