3

I have exactly the same problem like Kory Roberts in his unanswered post on osgeo.org: http://osgeo-org.1560.x6.nabble.com/Help-with-cached-join-layer-refresh-using-PyQGIS-td5352190.html

This is the content of the original post:


For reasons I won't go too deeply into, unless requested, I regularly need to run a very short PyQGIS query/filter code on 2 Spatialite layers:

query = '"id_a" IN (47, 120)' 
canvas = qgis.utils.iface.mapCanvas() 
allLayers = canvas.layers() 
for layer in allLayers: 
     if layer.name() == 'Layer_A': 
         layer.setSubsetString(query) 
     elif layer.name() == 'Layer_B': 
         layer.setSubsetString(query) 

Layer_A contains a geometry field, Layer_B does not. Layer_B is a view, which honestly is very slow to process. I have these joined in QGIS: Layer Properties -> Joins. For performance reasons, I have "Cache join layer in virtual memory" selected, otherwise editing is unbearably slow to the point that QGIS completely locks up for long periods of time.

The issue then, is that after I run the code subsequent times (changing for new queries), I have to go back into Layer Properties -> Joins -> specific join, click OK (without need to change any settings) to refresh the cache.

Probably a long way to this, but... Is there a way in PyQGIS to refresh the cache for the join layer and just add that line in at the end of the already existing code?


If there is no solution with python, maybe you could give me a hint to access the functionality in QGIS using C++ (like the OK Button in the Join section of the Layer Properties window does).

1 Answer 1

1

I was trying to solve a situation where an external process updates a Spatialite table which is part of a joined Vector layer in QGIS and despite using various methods in PyQGIS to try to trigger an update for the QgsVectorLayer, QgsDataSource or QgsVectorJoinBuffer objects without success.

What eventually worked for me was:

joins = layer.vectorJoins()
for join in joins:
    # Get layer as part of the join
    join_target = join.joinLayer()
    # Remove existing join
    layer.removeJoin(join.joinLayerId())
    # Create new join
    joinObject = QgsVectorLayerJoinInfo()
    joinObject.setUsingMemoryCache(True)
    joinObject.setJoinLayer(join_target)
    # Recreate the join
    layer.addJoin(joinObject)
layer.triggerRepaint()

This appears to update both geometry and the join attributes.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.