[processing] Use core connections API instead of Python GeoDB class

for postgres connection handling
This commit is contained in:
Nyall Dawson 2020-03-16 11:51:01 +10:00
parent c6ee7b6773
commit 97e47fa7b8
3 changed files with 59 additions and 30 deletions

View File

@ -31,12 +31,15 @@ from qgis.core import (QgsProcessing,
QgsProcessingParameterBoolean,
QgsProcessingParameterProviderConnection,
QgsProcessingParameterDatabaseSchema,
QgsProcessingParameterDatabaseTable)
QgsProcessingParameterDatabaseTable,
QgsProviderRegistry,
QgsProcessingException,
QgsProviderConnectionException,
QgsDataSourceUri)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils
from processing.tools.postgis import uri_from_name, GeoDB
from processing.tools.system import isWindows
@ -195,11 +198,16 @@ class Ogr2OgrToPostGisList(GdalAlgorithm):
return 'vectormiscellaneous'
def getConsoleCommands(self, parameters, context, feedback, executing=True):
connection = self.parameterAsConnectionName(parameters, self.DATABASE, context)
uri = uri_from_name(connection)
if executing:
# to get credentials input when needed
uri = GeoDB(uri=uri).uri
connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context)
# resolve connection details to uri
try:
md = QgsProviderRegistry.instance().providerMetadata('postgres')
conn = md.createConnection(connection_name)
except QgsProviderConnectionException:
raise QgsProcessingException(self.tr('Could not retrieve connection details for {}').format(connection_name))
uri = conn.uri()
ogrLayer, layername = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
shapeEncoding = self.parameterAsString(parameters, self.SHAPE_ENCODING, context)
@ -244,7 +252,7 @@ class Ogr2OgrToPostGisList(GdalAlgorithm):
arguments.append('-f')
arguments.append('PostgreSQL')
arguments.append('PG:"')
for token in uri.connectionInfo(executing).split(' '):
for token in QgsDataSourceUri(uri).connectionInfo(executing).split(' '):
arguments.append(token)
arguments.append('active_schema={}'.format(schema or 'public'))
arguments.append('"')

View File

@ -22,7 +22,6 @@ __date__ = 'October 2012'
__copyright__ = '(C) 2012, Victor Olaya'
from qgis.core import (QgsVectorLayerExporter,
QgsSettings,
QgsFeatureSink,
QgsProcessing,
QgsProcessingException,
@ -33,10 +32,13 @@ from qgis.core import (QgsVectorLayerExporter,
QgsProcessingParameterProviderConnection,
QgsProcessingParameterDatabaseSchema,
QgsProcessingParameterDatabaseTable,
QgsWkbTypes)
QgsWkbTypes,
QgsProviderRegistry,
QgsProviderConnectionException,
QgsDataSourceUri,
QgsAbstractDatabaseProviderConnection)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import postgis
class ImportIntoPostGIS(QgisAlgorithm):
@ -117,8 +119,14 @@ class ImportIntoPostGIS(QgisAlgorithm):
return self.tr('import,postgis,table,layer,into,copy').split(',')
def processAlgorithm(self, parameters, context, feedback):
connection = self.parameterAsConnectionName(parameters, self.DATABASE, context)
db = postgis.GeoDB.from_name(connection)
connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context)
# resolve connection details to uri
try:
md = QgsProviderRegistry.instance().providerMetadata('postgres')
conn = md.createConnection(connection_name)
except QgsProviderConnectionException:
raise QgsProcessingException(self.tr('Could not retrieve connection details for {}').format(connection_name))
schema = self.parameterAsSchema(parameters, self.SCHEMA, context)
overwrite = self.parameterAsBoolean(parameters, self.OVERWRITE, context)
@ -161,8 +169,11 @@ class ImportIntoPostGIS(QgisAlgorithm):
if source.wkbType() == QgsWkbTypes.NoGeometry:
geomColumn = None
uri = db.uri
uri.setDataSource(schema, table, geomColumn, '', primaryKeyField)
uri = QgsDataSourceUri(conn.uri())
uri.setSchema(schema)
uri.setTable(table)
uri.setKeyColumn(primaryKeyField)
uri.setGeometryColumn(geomColumn)
if encoding:
options['fileEncoding'] = encoding
@ -191,13 +202,16 @@ class ImportIntoPostGIS(QgisAlgorithm):
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))
if geomColumn and createIndex:
db.create_spatial_index(table, schema, geomColumn)
try:
options = QgsAbstractDatabaseProviderConnection.SpatialIndexOptions()
options.geometryColumnName = geomColumn
conn.createSpatialIndex(schema, table, options)
except QgsProviderConnectionException as e:
raise QgsProcessingException(self.tr('Error creating spatial index:\n{0}').format(e))
db.vacuum_analyze(table, schema)
try:
conn.vacuum(schema, table)
except QgsProviderConnectionException as e:
feedback.reportError(self.tr('Error vacuuming table:\n{0}').format(e))
return {}
def dbConnectionNames(self):
settings = QgsSettings()
settings.beginGroup('/PostgreSQL/connections/')
return settings.childGroups()

View File

@ -24,10 +24,11 @@ __copyright__ = '(C) 2012, Victor Olaya, Carterix Geomatics'
from qgis.core import (
QgsProcessingException,
QgsProcessingParameterString,
QgsProcessingParameterProviderConnection
QgsProcessingParameterProviderConnection,
QgsProviderRegistry,
QgsProviderConnectionException
)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import postgis
class PostGISExecuteSQL(QgisAlgorithm):
@ -64,13 +65,19 @@ class PostGISExecuteSQL(QgisAlgorithm):
return self.tr('postgis,database').split(',')
def processAlgorithm(self, parameters, context, feedback):
connection = self.parameterAsConnectionName(parameters, self.DATABASE, context)
db = postgis.GeoDB.from_name(connection)
connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context)
# resolve connection details to uri
try:
md = QgsProviderRegistry.instance().providerMetadata('postgres')
conn = md.createConnection(connection_name)
except QgsProviderConnectionException:
raise QgsProcessingException(self.tr('Could not retrieve connection details for {}').format(connection_name))
sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
try:
db._exec_sql_and_commit(str(sql))
except postgis.DbError as e:
raise QgsProcessingException(
self.tr('Error executing SQL:\n{0}').format(str(e)))
conn.executeSql(sql)
except QgsProviderConnectionException as e:
raise QgsProcessingException(self.tr('Error executing SQL:\n{0}').format(e))
return {}