2

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.

asked Dec 31, 2017 at 16:49
2
  • 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. Commented Dec 31, 2017 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 Commented Jan 1, 2018 at 12:22

3 Answers 3

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
answered Jan 1, 2018 at 11:43
1

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
answered Jan 1, 2018 at 13:55
1

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()
answered Dec 31, 2017 at 22:01
5
  • What if the dataset isn't shapefile? Commented Jan 1, 2018 at 1:02
  • @Vince you are right, I missed that :( Commented Jan 1, 2018 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)" Commented Jan 1, 2018 at 19:40
  • @ilFonta you will need to use layer.open(mode=dbf.READ_WRITE) after reading the file .. se here stackoverflow.com/questions/49314270/cant-write-dbf-file Commented Jan 28, 2022 at 10:47
  • I notice that dbf can only handle alphanumeric characters and _ in field names. Shape file however allows for other characters, such as () Commented Jan 28, 2022 at 10:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.