3

I want to edit a specific field for a QgsVectorLayer, within a QGIS application.

I am facing inconsistent results from my code, ie: changes are not alway commited. Please could someone point me to where it is wrong within this loop:

#vlayer is a QgsVectorLayer, imported from SQLITE DB
vlayer = QgsMapLayerRegistry.instance().mapLayer(layer)
caps = vlayer.dataProvider().capabilities()                
polygonGeom = QgsGeometry( rubberBand.asGeometry() ) 
#if vlayer is capable of edition
if caps & QgsVectorDataProvider.ChangeAttributeValues:

    vlayer.selectAll()

    for feature in vlayer.selectedFeatures():

        if feature.geometry() == None:
            continue

        if feature.geometry().intersects(polygonGeom):
            fid = feature.id()
            idx = vlayer.fieldNameIndex('some field')
            attr ={idx:'some value'}
            print fid,idx,attr
            vlayer.dataProvider().changeAttributeValues({fid:attr})

    vlayer.invertSelection()

Here is a post of my console showing that some features are selected and should be edited, but again, some are not properly updated to the underlying database.

2 16 {16: 4} 
12 16 {16: 4} 
13 16 {16: 4}
  • I made some changes to the code to follow explanation from the PyQgis dev. cookbook. section 4.2 Modification of a vector Layer without an editing buffer. Still unconsistent result. I can see that some features are selected from the loop criteria but not all of them are modified. – Peter Peterson Aug 20 '14 at 9:57
  • For a start, don't do this vlayer.selectAll(). Just for feature in vlayer.getFeatures() – Nathan W Aug 20 '14 at 10:15
  • By doing this, I can still see the loop doing the job, but now, nothing is udpated at all (tried to add a vlayer.updateFields() without success also) – Peter Peterson Aug 20 '14 at 10:28
  • for info, here is the way I initially wrote the sqlite file: QgsVectorFileWriter.writeAsVectorFormat(layer, layer.name(),"utf-8", None, "SQLite", False, None ,["SPATIALITE=YES",]) and the way I reloaded them to my application vlayer = QgsVectorLayer(vlayerpath, tablename, "spatialite"). And the output of vlayer = QgsMapLayerRegistry.instance().mapLayer('some name') gives me 'ogr' – Peter Peterson Aug 20 '14 at 10:46
  • 1
    would this work if you did it on a shapefile? Is this issue only on a spatialite db? – vinayan Aug 20 '14 at 12:20
2

I finally found out why field attributes weren't properly updated.

I was related to the data provider, but it is a very specific case because I made myself in trouble not using the 'ogr style' spatialite driver when writing my Spatialite files. Here is why it broke and how I repaired it:

  1. I am performing local extract of a PG database. I decided to store each table in a Sqlite/spatialite database.

  2. When writing, I used the writeAsVectorFormat method with "special" parameters to outpass some limitations that the QGIS API raise by using the "ogr style" spatialite driver. I already posted something here working with spatialite
    QgsVectorFileWriter.writeAsVectorFormat(layer, layer.name(),"utf-8", None, "SQLite", False, None ,["SPATIALITE=YES",]) (I needed to implant Triggers that worked with geometry)

But later in my application, I reloaded all these SQLITE files using the ogr library, which seemed to work.

So, the solution was to import my SQLITE files, using the actual spatialite data provider which allowed me to get proper results from the code I posted initially:

uri = QgsDataSourceURI()

uri.setDatabase("path to my sqlite db")
schema = ''
table = QgsMapLayerRegistry.instance().mapLayer(layer).name()
geom_column = 'GEOMETRY'
uri.setDataSource(schema, table, geom_column)

vlayer = QgsVectorLayer(uri.uri(), 'dummy', 'spatialite')
  • It is ok to mark this as answer if this solved your issue. – vinayan Aug 20 '14 at 13:03
  • @vinayan yes of course – Peter Peterson Aug 20 '14 at 13:35

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.