1

I have some vector shape files with many columns. I need to change the name of each column in the header from the old name to a more generic "Img1", "Img2", "Img3", etc progressively, starting from column #5 and leaving the name of columns 1 to 4 unchanged.

I wrote this Python code to be used with QGIS but it doesn't work.

layer = iface.activeLayer()
nImg = 1
nCol = len(layer.pendingFields())
cont = (5,nCol)
for field in cont:
    with edit (layer):
        oldName = layer.fieldNameIndex(field.name())
        newName = "Img" + str(nImg)
        layer.renameAttribute(oldName, newName)
    nImg = + 1

The error is

oldName = layer.fieldNameIndex(field.name())
AttributeError: 'int' object has no attribute 'name'

I tried also changing

with edit (layer) 

to

layer.startEditing() 

and unindenting the rows, but it doesn't work anyway.

  • Please Edit the question to specify whether you are trying to change the field presentation associated with the layer or the actual column names in the source table. – Vince Dec 31 '17 at 19:50
  • Hi Vince, I edited the text and I specified that I'm talking about shapefiles and I need to rename the header of the attribute tables. Cheers – ilFonta Jan 1 '18 at 12:22
2

The error is thrown by this line:

oldName = layer.fieldNameIndex(field.name())

and it is saying that field is an integer not an object with a name method. Also checking the documentation shows that:

int QgsFeature::fieldNameIndex ( const QString & fieldName )
const Utility method to get attribute index from name.

Field map must be associated using setFields() before this method can be used.

Parameters fieldName name of field to get attribute index of Returns -1 if field does not exist or field map is not associated.

So it looks up the index of a field based on its name, but you want to find the name based on its index. To do this you need to grab the qgsFields map using the fields method. So something like:

fields = layer.fields()
for field in cont:
with edit (layer):
    oldName = fields.at(field).name()
    newName = "Img" + str(nImg)
    layer.renameAttribute(oldName, newName)
nImg = + 1
0

This is the code that works for my issue

layer = iface.activeLayer()
nImg = 1
startCol = 5
endCol = len(layer.pendingFields())
countCol = (range(startCol,endCol,1))
for colNumber in countCol:
    with edit (layer):
        newName = "Img" + str(nImg)
        layer.renameAttribute(colNumber, newName)
        nImg = nImg + 1
0

If your GIS data format is shapefile then you can change the field names using the DBF python library as the attributes are defined in the DBF file:

import dbf
layer = dbf.Table('dbf_file')
cont = layer.field_names
try:
    for oldName in cont:
        newName = "Img" + str(nImg)
        layer.rename_field(oldName, newName)
        nImg = + 1
finally:
    layer.close()
  • What if the dataset isn't shapefile? – Vince Jan 1 '18 at 1:02
  • @Vince you are right, I missed that :( – Shiko Jan 1 '18 at 1:06
  • dbf library seems good, but I couldn't make it working. I get this error message "raise DbfError('%s not in read/write mode, unable to change field names' % meta.filename)" – ilFonta Jan 1 '18 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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