[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, QgsProcessingParameterBoolean,
QgsProcessingParameterProviderConnection, QgsProcessingParameterProviderConnection,
QgsProcessingParameterDatabaseSchema, QgsProcessingParameterDatabaseSchema,
QgsProcessingParameterDatabaseTable) QgsProcessingParameterDatabaseTable,
QgsProviderRegistry,
QgsProcessingException,
QgsProviderConnectionException,
QgsDataSourceUri)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils from processing.algs.gdal.GdalUtils import GdalUtils
from processing.tools.postgis import uri_from_name, GeoDB
from processing.tools.system import isWindows from processing.tools.system import isWindows
@ -195,11 +198,16 @@ class Ogr2OgrToPostGisList(GdalAlgorithm):
return 'vectormiscellaneous' return 'vectormiscellaneous'
def getConsoleCommands(self, parameters, context, feedback, executing=True): def getConsoleCommands(self, parameters, context, feedback, executing=True):
connection = self.parameterAsConnectionName(parameters, self.DATABASE, context) connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context)
uri = uri_from_name(connection)
if executing: # resolve connection details to uri
# to get credentials input when needed try:
uri = GeoDB(uri=uri).uri 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) ogrLayer, layername = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
shapeEncoding = self.parameterAsString(parameters, self.SHAPE_ENCODING, context) shapeEncoding = self.parameterAsString(parameters, self.SHAPE_ENCODING, context)
@ -244,7 +252,7 @@ class Ogr2OgrToPostGisList(GdalAlgorithm):
arguments.append('-f') arguments.append('-f')
arguments.append('PostgreSQL') arguments.append('PostgreSQL')
arguments.append('PG:"') arguments.append('PG:"')
for token in uri.connectionInfo(executing).split(' '): for token in QgsDataSourceUri(uri).connectionInfo(executing).split(' '):
arguments.append(token) arguments.append(token)
arguments.append('active_schema={}'.format(schema or 'public')) arguments.append('active_schema={}'.format(schema or 'public'))
arguments.append('"') arguments.append('"')

View File

@ -22,7 +22,6 @@ __date__ = 'October 2012'
__copyright__ = '(C) 2012, Victor Olaya' __copyright__ = '(C) 2012, Victor Olaya'
from qgis.core import (QgsVectorLayerExporter, from qgis.core import (QgsVectorLayerExporter,
QgsSettings,
QgsFeatureSink, QgsFeatureSink,
QgsProcessing, QgsProcessing,
QgsProcessingException, QgsProcessingException,
@ -33,10 +32,13 @@ from qgis.core import (QgsVectorLayerExporter,
QgsProcessingParameterProviderConnection, QgsProcessingParameterProviderConnection,
QgsProcessingParameterDatabaseSchema, QgsProcessingParameterDatabaseSchema,
QgsProcessingParameterDatabaseTable, QgsProcessingParameterDatabaseTable,
QgsWkbTypes) QgsWkbTypes,
QgsProviderRegistry,
QgsProviderConnectionException,
QgsDataSourceUri,
QgsAbstractDatabaseProviderConnection)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import postgis
class ImportIntoPostGIS(QgisAlgorithm): class ImportIntoPostGIS(QgisAlgorithm):
@ -117,8 +119,14 @@ class ImportIntoPostGIS(QgisAlgorithm):
return self.tr('import,postgis,table,layer,into,copy').split(',') return self.tr('import,postgis,table,layer,into,copy').split(',')
def processAlgorithm(self, parameters, context, feedback): def processAlgorithm(self, parameters, context, feedback):
connection = self.parameterAsConnectionName(parameters, self.DATABASE, context) connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context)
db = postgis.GeoDB.from_name(connection)
# 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) schema = self.parameterAsSchema(parameters, self.SCHEMA, context)
overwrite = self.parameterAsBoolean(parameters, self.OVERWRITE, context) overwrite = self.parameterAsBoolean(parameters, self.OVERWRITE, context)
@ -161,8 +169,11 @@ class ImportIntoPostGIS(QgisAlgorithm):
if source.wkbType() == QgsWkbTypes.NoGeometry: if source.wkbType() == QgsWkbTypes.NoGeometry:
geomColumn = None geomColumn = None
uri = db.uri uri = QgsDataSourceUri(conn.uri())
uri.setDataSource(schema, table, geomColumn, '', primaryKeyField) uri.setSchema(schema)
uri.setTable(table)
uri.setKeyColumn(primaryKeyField)
uri.setGeometryColumn(geomColumn)
if encoding: if encoding:
options['fileEncoding'] = encoding options['fileEncoding'] = encoding
@ -191,13 +202,16 @@ class ImportIntoPostGIS(QgisAlgorithm):
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage())) self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))
if geomColumn and createIndex: 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 {} 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 ( from qgis.core import (
QgsProcessingException, QgsProcessingException,
QgsProcessingParameterString, QgsProcessingParameterString,
QgsProcessingParameterProviderConnection QgsProcessingParameterProviderConnection,
QgsProviderRegistry,
QgsProviderConnectionException
) )
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import postgis
class PostGISExecuteSQL(QgisAlgorithm): class PostGISExecuteSQL(QgisAlgorithm):
@ -64,13 +65,19 @@ class PostGISExecuteSQL(QgisAlgorithm):
return self.tr('postgis,database').split(',') return self.tr('postgis,database').split(',')
def processAlgorithm(self, parameters, context, feedback): def processAlgorithm(self, parameters, context, feedback):
connection = self.parameterAsConnectionName(parameters, self.DATABASE, context) connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context)
db = postgis.GeoDB.from_name(connection)
# 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', ' ') sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ')
try: try:
db._exec_sql_and_commit(str(sql)) conn.executeSql(sql)
except postgis.DbError as e: except QgsProviderConnectionException as e:
raise QgsProcessingException( raise QgsProcessingException(self.tr('Error executing SQL:\n{0}').format(e))
self.tr('Error executing SQL:\n{0}').format(str(e)))
return {} return {}