9

How can I rename a field in PyQGIS?

I tried:

for field in layer.pendingFields():
if field.name() == 'old':

    layer.startEditing()
    oldname = field.name()
    field.setName('new')
    newname = field.name()
    print(u'Old name: {}, New name: {}'.format(oldname,newname))
    layer.commitChanges()

This code prints 'Old name: old, New name: new', but in the attribute table the field name is still 'old'.

Taras
  • 32,823
  • 4
  • 66
  • 137
Peter Frank
  • 155
  • 1
  • 6

3 Answers3

9

PyQGIS 3

Use this one:

layer = iface.activeLayer()

for field in layer.fields(): if field.name() == 'old_fieldname':

    with edit(layer):
        idx = layer.fields().indexFromName(field.name())
        layer.renameAttribute(idx, 'new_fieldname')

Or try this function:

def rename_dp_field(rlayer, oldname, newname):
  findex = rlayer.dataProvider().fieldNameIndex(oldname)
  if findex != -1:
    rlayer.dataProvider().renameAttributes({findex: newname})
    rlayer.updateFields()
Taras
  • 32,823
  • 4
  • 66
  • 137
Abel
  • 135
  • 1
  • 3
5

I think the QgsField::setName() method is only used for creating new fields.

If you want to rename your field, you can use QgsVectorLayer::renameAttribute() method in QGIS 2.16 and above:

layer = iface.activeLayer()

for field in layer.pendingFields(): if field.name() == 'old':

    with edit(layer):
        idx = layer.fieldNameIndex(field.name())
        layer.renameAttribute(idx, 'new')

Taras
  • 32,823
  • 4
  • 66
  • 137
Joseph
  • 75,746
  • 7
  • 171
  • 282
  • I used this code to update the field names 3 times sequentially, and it worked flawlessly the first two times. The third attempt at renaming the field yielded a 'layer not editable' error, which is strange considering the layer was edited twice immediately before then. Do you have any insight for why this is occurring? – GIS_Canuck Jul 11 '17 at 18:10
  • If I change the 'with edit(layer)' line to 'layer.startEditing()', and then unindent the rest of the code, there are no problems updating the final field. Not sure why this is happening, but thankfully everything is working as anticipated now. – GIS_Canuck Jul 11 '17 at 19:05
  • @GIS_Canuck - That is strange, not sure why with edit(layer) is a problem. Sounds like a bug to me. You could consider posting a bug report with a reproducible method but glad you found another method :) – Joseph Jul 12 '17 at 08:58
  • 2
    in QGis 3, QgsVectorLayer.fieldNameIndex is replaced by fields().lookupField() or fields().indexFromName() (see here). In this example, replace idx = layer.fieldNameIndex(field.name()) by idx = layer.pendingFields().indexFromName(field.name()) – Lennert Feb 27 '18 at 11:05
  • It doesn't work for 2.84 – Chetan Vashisth Nov 12 '19 at 12:45
  • @ChetanVashisth - Is that 2.8.4? The method should work for 2.16 onwards, could you not use the latest QGIS 3 version? – Joseph Nov 12 '19 at 12:50
  • I am currently using a script in QGIS 2.84 WIen not 2.8.4 so mine is is the previous version of 2.18 LTR so i am unable to rename the fields and still trying to find something from last 2 days. Just let me know any alternative if you have any info about. – Chetan Vashisth Nov 12 '19 at 13:08
  • @ChetanVashisth - I think it would be better if you asked this as a new question and reference this post to show you tried this method and it did not work. Include your script and describe whether you receive any errors or if the field doesn't get renamed. – Joseph Nov 12 '19 at 13:11
2

edit(layer) may cause trouble in a "standalone" script, I got an error name 'edit' is not defined so I found another way. I made this example with an activeLayer() :

layer = iface.activeLayer()

# Open editing session
layer.startEditing()

# Rename field
for field in layer.fields():
    if field.name() == 'oldName':
        idx = layer.fields().indexFromName(field.name())
        layer.renameAttribute(idx, 'newName')

# Close editing session and save changes
layer.commitChanges()
GeoGyro
  • 1,636
  • 1
  • 15
  • 35