0

I'm developing a standalone QGIS based Python script for loading layers from/to PostgreSQL/PostGIS database. If I check the list using code:

providers = QgsProviderRegistry.instance().providerList()

I'm getting only GDAL. I have tested with

print(QgsProviderRegistry.instance().providerMetadata('postgres'))

but it is giving None

My syste details are as follows:

OS:Windows 10 
QGIS:3.16.11

How can I include PostgreSQL extension in the qgsProviderRegistry?

Satya Chandra
  • 1,409
  • 4
  • 23
  • 47

2 Answers2

1

Unable to reproduce with the following code (Python 3.16 on Linux)

import sys
from qgis.core import (QgsApplication, QgsProviderRegistry)

app = QgsApplication([], True)

On Linux, didn't need to set it so commented

app.setPrefixPath("C:/Program Files/QGIS Brighton/apps/qgis", True)

app.initQgis()

providers = QgsProviderRegistry.instance().providerList() print(providers)

above statement returns

['DB2', 'OAPIF', 'WFS', 'arcgisfeatureserver', 'arcgismapserver', 'delimitedtext', 'gdal', 'geonode', 'gpx', 'mdal', 'memory', 'mesh_memory', 'mssql', 'ogr', 'ows', 'postgres', 'postgresraster', 'spatialite', 'vectortile', 'virtual', 'wcs', 'wms']

It clearly seems related to your library path when loading standalone Python script.

ThomasG77
  • 30,725
  • 1
  • 53
  • 93
  • If I ran above code I'm getting ['gdal', 'memory', 'mesh_memory', 'ogr', 'vectortile']. – Satya Chandra Oct 14 '21 at 04:50
  • What is the ouptut of QgsProviderRegistry.instance().libraryDirectory().path() ? within QGIS Python console? What is the value within your standalone script? – ThomasG77 Oct 14 '21 at 08:43
0

This thread is old but there are no further discussions about this topic.

My setting is: qgis(-server) running in a container, local conda create env qgis.

I think its not related to the platform. In a conda env with qgis (3.30) I have the same redcuced provider list as stated in comments before.

I also tried to set the setPrefixPath to env/qgis/share/qgis or env/qgis/lib where the *postgres*.so is located but no luck.

Maybe it works if env/qgis/lib is added to sys.path initially, but untested.

So a solution can be to read the credentials from the layer by reading the qgs xml file with e.g. xmltodict and psycopg2 to accesss the layer.

If processing algs should be used then the layer needs to be recreated as a QgsVectorLayer from the select query.

But the problem of missing postgres provider in the qgis package by installing with conda create env qgis remains.

Update

i wanted to use processing where i had to call Processing.initialize(). I did call it before initQgis(). As stated here the providers should load with that command. But if Processing.initialize() is called before not all providers, e.g. postgres are loaded.

Well in the docs it is stated after initQgis(): Write your code here to load some layers, use processing algorithms, etc.

that was not clear to me as i thought calling Processing.initialize() where processing providers QgsProcessingProvider are appended to QgsApplication.processingRegistry() does not affect QgsApplication().initQgis().

import os
from qgis.core import QgsApplication,QgsProviderRegistry
from processing.core.Processing import Processing

os.environ["QT_QPA_PLATFORM"] = "offscreen"

def run(): qgs = QgsApplication([], False) # # this does not work # Processing.initialize() qgs.initQgis() Processing.initialize() print("provider path: ", QgsProviderRegistry.instance().libraryDirectory().path()) print("provider list: ",QgsProviderRegistry.instance().providerList()) run()