3

I am trying to create a temporary layer in a script but I can't get the attributes defined:

# create layer
    vl = QgsVectorLayer("Points", name, "memory")
    vl.addAttribute(QgsField('name', 10))

    print [f.name() for f in vl.pendingFields()]

prints []

Clearly I am missing something

I am working off code from replacement-of-qvariant-and-setattributemap-in-pyqgis

2
5

You are missing a couple important lines of code and the syntax is slightly off, try:

vl = QgsVectorLayer("Point", name, "memory") # removed "s" on Points
pr = vl.dataProvider() # need to create a data provider
pr.addAttributes([QgsField("name",  QVariant.Int)]) # define/add field data type
vl.updateFields() # tell the vector layer to fetch changes from the provider
1
  • Ah! you add the attributes to the provider not the layer, that's what I had confused. I miscopied the example and no amount of staring at the code helped. Clearly layer also has a addAttributes method! Jul 24 '17 at 2:16
3

I'm adding more information than previous answers.

It depends if want to update straight the data source under your QgsVectorLayer (such as Geojson file, PostgresSQL database, Geopackage...). You may have some database triggers, some foreign keys with some 1-N relationships and if you want to be able to rollback your changes.

If you want to use the editing buffer, like you do in QGIS desktop when you turn on/off the "editing session":

layer = QgsVectorLayer('Point', name, 'memory')
layer.startEditing()
# In the QGIS GUI, you can see the 'pen' on your layer
layer.addAttributes([QgsField('name',  QVariant.Int)]) # define/add field data type
layer.commitChanges()

QGIS will manage to send all your changes only after you are committing. This is the recommended way, because you don't send your modification straight to your real data. You can still use layer.rollback() if you want to cancel your changes.

But if you need to send your modification straight to your datasource, you indeed need to use the dataProvider:

layer = QgsVectorLayer('Point', name, 'memory')
data_provider = layer.dataProvider()  # you access the real datasource behind your layer (for instance PostGIS)
data_provider.addAttributes([QgsField('name',  QVariant.Int)])
layer.updateFields()  # update your vector layer from the datasource

Using the dataProvider, it's not possible to rollback, because you updated your datasource directly. You are not like in the QGIS UI where you have an "editing session".

Like a lot of examples on the internet, no need to use both methods at the same time. Use one or the other one.

1
provider = layerJ.dataProvider()
provider.addAttributes( [ QgsField('new_field', QVariant.String)])
layer.updateFields()

This help to add attributes to new layer

  • data provider() is the connection to the underlying file or database that holds the geospatial information to be displayed.

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.