5

I am trying to create a new attribute field "FromNode" in a layer that contains string with an integer.

EXAMPLE: name1, name2, name3, name4, ... till the end of the table.

I got the solution by doing manually in QGIS Field Calculator.

concat('name', "id")

The manual procedure is tedious due to multiple layers.

Is there a way to automatically do this using PyQGIS or even SQL query in Virtual layer approach?

Attempt in PyQGIS

Problem: It only creates empty 'String' field. I want to update the field with string "Name" + increment of "integer 1" in each row. For instance, name1, name2, name3, ...

layer = iface.activeLayer()

myField = QgsField('FromNode', QVariant.String,'character', 200)
layer.dataProvider().addAttributes([myField])
layer.updateFields()
3

1 Answer 1

9

You can use the code below:

lyr = iface.activeLayer()
lyr.dataProvider().addAttributes([QgsField('FromNode', QVariant.String, '', 20)])
lyr.updateFields()
fld_idx = lyr.fields().lookupField('FromNode')
for count, f in enumerate(lyr.getFeatures()):
    lyr.dataProvider().changeAttributeValues({f.id(): {fld_idx: f'name{count+1}'}})

Edit in response to further request in comment (start count at 6000):

lyr = iface.activeLayer()
lyr.dataProvider().addAttributes([QgsField('FromNode', QVariant.String, '', 20)])
lyr.updateFields()
fld_idx = lyr.fields().lookupField('FromNode')
count = 6000
for f in lyr.getFeatures():
    lyr.dataProvider().changeAttributeValues({f.id(): {fld_idx: f'name{count}'}})
    count += 1

Edit 2 in response to further subsequent request. After running the code above to add and populate the 'FromNode' field, run the code below:

lyr = iface.activeLayer()

fld_list = [QgsField('baseVoltag', QVariant.String, '', 20),
            QgsField('headTermin', QVariant.String, '', 20),
            QgsField('class', QVariant.String, '', 20)]
            
lyr.dataProvider().addAttributes(fld_list)
lyr.updateFields()
fld_values = ['415V', NULL, 'EnergyConsumer']
att_map = {}
for i, fld in enumerate(fld_list):
    att_map[lyr.fields().lookupField(fld.name())] = fld_values[i]

for feat in lyr.getFeatures():
    lyr.dataProvider().changeAttributeValues({feat.id(): att_map})

Resulting attribute table shown below:

enter image description here

6
  • Thank you. The above solution create new field 'FromNode' in all layers. How to restrict it to the active layer or by name of the layer? Oct 6, 2021 at 6:11
  • Great. Is it possible to start the count in the field with 6000 and then incremented with 1. For example, 6001,6002,..... Oct 6, 2021 at 6:19
  • 1
    @user12729159, I have updated my answer. I don't really understand though. The following remark in your question: "The manual procedure is tedious due to multiple layers" gave the impression that you wanted to perform the operation on multiple layers.
    – Ben W
    Oct 6, 2021 at 6:25
  • 1
    Answer updated again!
    – Ben W
    Oct 6, 2021 at 6:26
  • 1
    @user12729159, see latest update!
    – Ben W
    Oct 6, 2021 at 12:04

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.