I am writing a plugin that updates 2 fields in an existing spatialite layer. The spatialite table contains several layers which are displayed on the current map. It executes to completion (very slowly), but the updates aren't appearing and I am getting an error that states:
SQLite error: database is locked SQL:
I've tried putting the layer into edit mode before running the plugin and also calling startEditing() on the layer within the code.
def run(self):
#bunch of code that works self.bRanges created here
layer_name = self.dlg.cbStreets.currentText()
self.layer = layer_list[layer_name]
self.from2 = self.layer.fields().fieldNameIndex('from2')
self.to2 = self.layer.fields().fieldNameIndex('to2')
self.dp = self.layer.dataProvider()
self.layer.startEditing()
self.processEachVectorCount(self.updateRanges, 10)
self.layer.commitChanges()
def processEachVectorCount(self, func, count):
iter = self.layer.getFeatures()
counter = 1
for feature in iter:
func(feature)
counter = counter + 1
if counter == count:
break
def updateRanges(self, feature):
# self.bRanges is a dict with a list as values
bRange = self.bRanges.get(feature.attribute('road_id'))
fid = feature.id()
if bRange and len(bRange):
bMin = min(bRange)
bMax = max(bRange)
print feature.attribute('full_name'), bMin, bMax
#I'm seeing this print, so far so good
attrs = {self.from2: bMin, self.to2:bMax}
self.dp.changeAttributeValues({fid:attrs})
EDIT: The following code works.
def run(self):
... same setup as above, but no need to set the dataprovider
self.layer.startEditing()
self.processEachVectorCount(self.updateRanges, 10)
self.layer.commitChanges()
def updateRanges(self, feature):
... again, same as above
self.layer.changeAttributeValue(fid, self.from2, bMin)
self.layer.changeAttributeValue(fid, self.to2, bMax)
The commitChanges call isn't strictly necessary. Without it the layer is left in edit mode.
layer.startEditing()
andlayer.commitChanges()
) you should uselayer.changeAttributeValue()
etc and notlayer.dataProvider().changeAttributeValues()
etc.self.layer.changeAttributeValue(fid, self.from2, bMin)
etc seems to work, but it still raises the error 5 seconds or so after execution end.