I want to delete specific columns in the attribute table of my layer:
except for the "LAYER"
Column.
This is my code:
clip = processing.runAndLoadResults("native:clip",
{ 'INPUT': union['OUTPUT'],
'OVERLAY': dissolved['OUTPUT'],
'OUTPUT': 'TEMPORARY_OUTPUT',
})
# field names to be deleted
fields = ['fid_2',
'fid',
'Phasenr_2',
'fid_3',
'Phasename',
'layer',
'path']
# get field ids from field names
field_ids = [clip.field().indexFromName(f) for f in fields]
# delete the attribute using their index
clip.dataProvider().deleteAttributes(field_ids)
clip.updateFields()
Error:
Traceback (most recent call last):
File "C:\PROGRA~1\QGIS32~1.0\apps\Python39\lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "<string>", line 69, in <module>
File "<string>", line 69, in <listcomp>
AttributeError: 'dict' object has no attribute 'field'
-
2Does this answer your question? Deleting column/field in PyQGISTaras– Taras ♦2023年03月18日 07:47:53 +00:00Commented Mar 18, 2023 at 7:47
-
@Taras This question is a bit different.Kadir Şahbaz– Kadir Şahbaz2023年03月19日 17:23:47 +00:00Commented Mar 19, 2023 at 17:23
2 Answers 2
clip.field
must beclip.fields
processing.runAndLoadResult
method returns a dictionary like{"OUTPUT": 'result/file/temporary/path'}
. Soclip
is a dictionary.fields
is aQgsVectorLayer
method. This is why you get the error.In your case, using
processing.run
is more appropriate. It again returns a dictionary, but, containing aQgsVectorLayer
. In this case, you have to add the layer manually usingQgsProject.instance().addMapLayer()
.
So, the script you need:
clip = processing.run("native:clip",
{ 'INPUT': union['OUTPUT'],
'OVERLAY': dissolved['OUTPUT'],
'OUTPUT': 'TEMPORARY_OUTPUT',
})["OUTPUT"] ###
QgsProject.instance().addMapLayer(clip)
# field names to be deleted
fields = ['fid_2', 'fid', 'Phasenr_2', 'fid_3', 'Phasename', 'layer', 'path']
# get field ids from field names
field_ids = [clip.fields().indexFromName(f) for f in fields]
# delete the attribute using their index
clip.dataProvider().deleteAttributes(field_ids)
clip.updateFields()
You can also construct the field names to be deleted using the field names not to be deleted as follows:
dont_delete = ["LAYER", "otherfield"]
all_fields = clip.fields().names()
field_ids = [clip.fields().indexFromName(f) for f in all_fields if f not in dont_delete]
Old answer:
You didn't define inlayDir_provider
. You also have to get the field index to pass it to deleteAttributes
method. It takes field indices as argument, not field names.
Deleting single attribute:
inlayDir = iface.activeLayer()
# get field index
field_index = inlayDir.fields().indexFromName('fid_2')
# delete the attribute using its index
inlayDir.dataProvider().deleteAttributes([field_index])
inlayDir.updateFields()
Deleting specific attributes:
inlayDir = iface.activeLayer()
# field names to be deleted
fields = ["field1", "field2", "field3"]
# get field ids from field names
field_ids = [inlayDir.fields().indexFromName(f) for f in fields]
# delete the attribute using their index
inlayDir.dataProvider().deleteAttributes(field_ids)
inlayDir.updateFields()
QGIS 3.34 and geojson files, deleteAttributes fails : columns are deleted, but it does not keep the rights data (like columns shift)
Similar solution calling Processing deletecolumn or retainfields
processing.run("native:retainfields", {'INPUT':'zzz','FIELDS':['nom','superficie'],'OUTPUT':'TEMPORARY_OUTPUT'})
or native:deletecolumn") works fine.
Explore related questions
See similar questions with these tags.