I need to create a new field and calculate some values in a file (shapefile or gpkg) with more than 65_000 rows.
The quickest way I found was using the processing module with the native:fieldcalculator tool :
from qgis.gui import *
from math import ceil
import processing
Function used to calculate the new field - the content is not important for this question
@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def estimate_time_since_last_pert(pert_years, profile_year, feature, parent):
pert_years = [float(t) for t in pert_years if t != NULL]
if not pert_years:
return 100
last_pert_year = max(pert_years)
time_since_last_pert = profile_year - last_pert_year
return int(5 * ceil((time_since_last_pert) / 5))
Args of the Field Calculator tool and running the tool
alg_params = {
'FIELD_LENGTH': 4,
'FIELD_NAME': 'TEMPSCoupe',
'FIELD_PRECISION': 0,
'FIELD_TYPE': 1, # Integrer
'NEW_FIELD': True,
'FORMULA': 'estimate_time_since_last_pert(array(AN_ORIGINE, AN_PERTURB), 2020)',
'INPUT': 'src_file.shp',
'OUTPUT': 'dst_file.shp',
}
processing.run('native:fieldcalculator', alg_params)
However, I can't find a way to modify my input file instead of having to create a new one. Is this possible ?
execute_in_placemethod does not work on a file but on a loaded layer ->QgsVectorLayer(file_path, 'name', 'ogr'). It will return an exception if theINPUTarg is a path :AttributeError: 'str' object has no attribute 'createExpressionContextScope'. So the modification are done in the memory and I need to save the layer object into a file (which comes back to the same thing but slower from the fieldcalculator from my testing :/ ) – Paulloed Jun 16 '23 at 18:03