7

Is there a way to remove all but one of the fields in the attribute table (with a pre-known name) using QGIS 3 Model Builder?

The problem is, I don't want to include all of these names in the model builder (besides they might not be known beforehand).

  • 1
  • 2
    I haven't used the model builder but instead of dropping an unknown number of columns could you just select the column you want to keep into a new table? – M Bain Oct 1 at 10:02
  • @MBain The problem is that you can't do this in the model builder because you don't know the field names before you start processing. – Comrade Che Oct 1 at 10:17
  • 2
    Added a new pull request to avoid using third-party scripts: github.com/qgis/QGIS/pull/39114 – Comrade Che Oct 1 at 11:16
  • 1
    Could you explain - with some example fields - what you're trying to do? From your original question, seems like @MBain's comment would work since you say you do have a 'pre-known name' to select, and just want to drop the other fields? – Simbamangu Oct 1 at 12:47
5

You can use the algorithm 'Refactor Fields' in the Model Builder.

enter image description here

For 'source expression' and 'name' in the Refactor dialog, use the field name that you know from your input; that will be the only field remaining in the output vector.

You can use the 'load fields from template layer' option to get correctly-entered fields, then use the 'delete selected field' button to remove the ones you don't want.

enter image description here

| improve this answer | |
  • Thank you, exactly what I need. – Comrade Che Oct 2 at 5:14
5

If you don't mind playing around with Python a bit - you could export the model to a Python script using the option Export as Script Algorithm... in the Processing Modeler window.

Then you could inject this piece of code and run the exported script. Of course then you can easily implement your logic of passing the field name dynamically.

#INPUT - fields to remain
fieldsToRemain = ["id", "temp_id"]

#vlayer is a QgsVectorLayer object
fields = vlayer.fields()
print([f.name() for f in fields])

fieldsToDelete = []
for field in [f for f in fields if not f.name() in fieldsToRemain]:
    idx = fields.indexFromName(field.name())
    fieldsToDelete.append(idx)

vlayer.startEditing()
vlayer.deleteAttributes(fieldsToDelete)
vlayer.commitChanges()

#only the desired fields are left
print([f.name() for f in vlayer.fields()])
| 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.