4

I get this error KeyError: 'FieldOne' when I try to add a new attribute value to my feature. This is the code that I use to create a new Layer:

v_layer = QgsVectorLayer('LineString?crs=epsg:4326', 'layerName', 'memory')
pr = v_layer.dataProvider()
pr.addAttributes([QgsField('FieldOne',  QVariant.String)])
pr.addAttributes([QgsField('FieldTwo',  QVariant.String)]) 
v_layer.updateFields()
QgsProject.instance().addMapLayers([v_layer])

After creating the new layer, I need to fill it with new features. Each feature has his attributes. Using this code that give me the error KeyError: 'FieldOne'.

def createNewFeature(fieldone,fieldtwo):
  seg = QgsFeature()
  seg.setGeometry(QgsGeometry.fromPolyline([start_point, end_point]))  
  pr.addFeatures( [ seg ] )
  v_layer.startEditing()
  seg['FieldOne']=fieldone
  seg['FieldTwo']=fieldtwo 
  v_layer.updateFeature(seg)  
  v_layer.commitChanges() 
  • You don't have quotes around layerName. Replace v_layer = QgsVectorLayer('LineString?crs=epsg:4326', layerName, 'memory') with v_layer = QgsVectorLayer('LineString?crs=epsg:4326', 'layerName', 'memory'). – jdavid05 Feb 25 at 18:53
  • Yes, sorry. It's a mistake here, but in the code it's correct – Lorenzo Feb 25 at 18:56
5

A warning in updateFeature() documentation:

This method needs to query the underlying data provider to fetch the feature with matching QgsFeature.id() on every call.

Try in this way:

v_layer.startEditing()
iterator = v_layer.getFeatures()
seg = next(iterator)
seg["FieldOne"] = "fieldone"
seg["FieldTwo"] = "fieldtwo"
v_layer.updateFeature(seg)  
v_layer.commitChanges() 

or in this way for all features:

v_layer.startEditing()
for seg in v_layer.getFeatures():
    seg["FieldOne"] = "fieldone"
    seg["FieldTwo"] = "fieldtwo"
    v_layer.updateFeature(seg)  
v_layer.commitChanges() 

EDIT: If you want to set the values ("fieldone","fieldtwo") only for the feature that you just created, you have to set fields for new QgsFeature object using setFields() method.

def createNewFeature(fieldone, fieldtwo):
    seg = QgsFeature()

    # set fields for new object
    seg.setFields(v_layer.fields())

    # set attribute values for fields
    seg['FieldOne'] = fieldone
    seg['FieldTwo'] = fieldtwo

    # set geometry. change start and end points
    seg.setGeometry(QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)]))

    # add new feature to the layer
    pr.addFeatures([seg])


v_layer = QgsVectorLayer('LineString?crs=epsg:4326', 'layerName', 'memory')
pr = v_layer.dataProvider()
pr.addAttributes([QgsField('FieldOne',  QVariant.String)])
pr.addAttributes([QgsField('FieldTwo',  QVariant.String)]) 
v_layer.updateFields()
QgsProject.instance().addMapLayers([v_layer])

createNewFeature("field one", "field two")
| improve this answer | |
  • Hi thanks for your answer. I want to set that values ("fieldone","fieldtwo") only for the feature that I just created. The part of my code starting from seg = QgsFeature() probably will be enclosed in a function that will add to the layer new features and the values ("fieldone","fieldtwo") will be different for each features. – Lorenzo Feb 25 at 19:37
  • Thank you, this is what i was looking for. Sorry about unclear question. – Lorenzo Feb 25 at 19:58
  • 2
    I made some changes, please review. – Kadir Şahbaz Feb 25 at 20:04
3

You can use the setAttributes function:

v_layer = QgsVectorLayer('LineString?crs=epsg:4326', 'layerName2', 'memory')
pr = v_layer.dataProvider()
pr.addAttributes([QgsField('FieldOne',  QVariant.String)])
pr.addAttributes([QgsField('FieldTwo',  QVariant.String)]) 
v_layer.updateFields()
QgsProject.instance().addMapLayers([v_layer])
seg = QgsFeature()
seg.setGeometry(QgsGeometry.fromPolyline([QgsPoint(10,10),QgsPoint(11,11)]))
seg.setAttributes(["a","b"])
pr.addFeatures([seg])

You just set the attributes with the coordinates as you create the feature.

| improve this answer | |

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.