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).

7
  • 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 '20 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. Oct 1 '20 at 10:17
  • 2
    Added a new pull request to avoid using third-party scripts: github.com/qgis/QGIS/pull/39114 Oct 1 '20 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 '20 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

1
  • Thank you, exactly what I need. Oct 2 '20 at 5:14
6

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()])

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.