Pregunta:
Quiero editar algunos campos en un GeoPackage (descargar un.gpkg)
# -*- coding: utf-8 -*-
from osgeo import ogr
from time import clock
print ("Start",clock())
source = ogr.Open("c:/.../a.gpkg",update=True)
layer = source.GetLayerByName( "263c6845-e2c3-4eee-ae26-f0e9539f3c2bP" )
laydef = layer.GetLayerDefn()
i=0
feature = layer.GetNextFeature()
while feature:
i=i+1
# make some stuff
# .....
layer.SetFeature(feature)
feature = layer.GetNextFeature()
source.Destroy()
print ("Finish",i,clock())
('Inicio', 3.4136520136791866e-07) ('Finalizar', 1612, 243.56666043106233)
Funciona, pero lleva mucho tiempo (4 minutos para 1.600 registros).
¿Qué va mal?
Respuesta:
Realice un cambio menor pero importante y haga que todas las ediciones se realicen dentro de una transacción en lugar de realizar una transacción para cada fila. Las transacciones son bastante caras para SQLite y, por lo tanto, también para GeoPackage. Hacer menos transacciones pero más grandes es más rápido. Puede encontrar algunos números en https://stackoverflow.com/questions/1711631/improve-insert-per-second-performance-of-sqlite .
Un guión modificado:
# -*- coding: utf-8 -*-
from osgeo import ogr
from time import clock
print ("Start",clock())
source = ogr.Open("a.gpkg",update=True)
layer = source.GetLayerByName( "263c6845-e2c3-4eee-ae26-f0e9539f3c2bP" )
laydef = layer.GetLayerDefn()
layer.StartTransaction()
i=0
feature = layer.GetNextFeature()
while feature:
i=i+1
# make some stuff
# .....
layer.SetFeature(feature)
feature = layer.GetNextFeature()
layer.CommitTransaction()
source.Destroy()
print ("Finish",i,clock())
Compare los tiempos:
Con una transacción
python run_a.py
('Start', 7.292488590901599e-07)
('Finish', 1612, 0.09405851784544883)
Guión original sin transacción:
python run_a.py
('Start', 7.292488590901599e-07)
('Finish', 1612, 15.54201567301648)
Tengo un disco SSD que puede explicar por qué su secuencia de comandos original es considerablemente más rápida para mí (15,5 segundos frente a 243,56 segundos).