Firstly, regarding the errors you are getting. Here you are storing the layer Data Provider object in the pr variable:
pr = vl.dataProvider()
Then in these lines:
pr.dataProvider().addAttributes(fields)
pr.updateFields()
You are calling dataProvider()
and updateFields()
on the QgsVectorDataProvider
object, however, these methods come from the QgsMapLayer
and QgsVectorLayer
classes, so both will cause errors.
If your goal is to update your "fid" field all at once after you have added some features, you can just do this:
with edit(vl):
for f in vl.getFeatures():
f['fid'] = f.id()
# Or if you want your fid to start from zero instead of 1...
#f['fid'] = f.id()-1
vl.updateFeature(f)
However, you should know that this approach you are attempting will not have any any effect at the time a feature is added, it will simply update the "fid" column for already existing features.
It sounds to me like what you really want is to set a default value for your "fid" field during the layer creation using pyqgis, so that when any feature is added, the "fid" field is automatically filled with incrementing integers. In that case, you can use the following code:
vl = QgsVectorLayer("Polygon?crs=epsg:28355", "blank_poly", "memory")
pr = vl.dataProvider()
pr.addAttributes( [ QgsField("fid", QVariant.Int),
QgsField("Label", QVariant.String,'character', 255),
QgsField("Source", QVariant.String),
QgsField("Date", QVariant.Date),
QgsField("Status", QVariant.String),
QgsField("Theme", QVariant.String),
QgsField("SubTheme", QVariant.String),
QgsField("Comments", QVariant.String,'character', 255),
QgsField("Area", QVariant.String),
QgsField("Name", QVariant.String)] )
vl.updateFields()
default_val = QgsDefaultValue(
"""
CASE
WHEN maximum("fid") is NULL THEN 1
WHEN "fid" is NULL THEN maximum("fid")+1
ELSE "fid"
END
""",
applyOnUpdate=True)
vl.setDefaultValueDefinition(vl.fields().lookupField('fid'), default_val)
QgsProject.instance().addMapLayer(vl)
vl.startEditing()
Again, if you want your "fid" to start from zero instead of one, change the expression to:
"""
CASE
WHEN maximum("fid") is NULL THEN 0
WHEN "fid" is NULL THEN maximum("fid")+1
ELSE "fid"
END
"""
Best Answer
You can use the following recipe as it does not involve any third party library like
psycopg2
as there is a native support for what you want in PyQGIS.Edit due to question in question :)
You may try to check if database exists going through the postgres database (that always exists in a PostgreSQL instance)