[processing][gdal] Better error messages when invalid parameters are passed

This commit is contained in:
Nyall Dawson 2018-05-06 10:29:01 +10:00
parent 787dd3413e
commit f4599f13f1
28 changed files with 142 additions and 34 deletions

View File

@ -29,7 +29,8 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsProcessingParameterRasterLayer,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterCrs,
QgsProcessingOutputRasterLayer)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
@ -78,6 +79,9 @@ class AssignProjection(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
fileName = inLayer.source()
crs = self.parameterAsCrs(parameters, self.CRS, context).authid()

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterEnum,
@ -110,6 +111,9 @@ class ClipRasterByExtent(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException('Invalid input layer {}'.format(parameters[self.INPUT] if self.INPUT in parameters else 'INPUT'))
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, inLayer.crs())
if self.NODATA in parameters and parameters[self.NODATA] is not None:
nodata = self.parameterAsDouble(parameters, self.NODATA, context)

View File

@ -31,6 +31,7 @@ from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterRasterLayer,
@ -124,6 +125,8 @@ class ClipRasterByMask(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
maskLayer, maskLayerName = self.getOgrCompatibleSource(self.MASK, parameters, context, feedback, executing)

View File

@ -27,6 +27,7 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -102,6 +103,9 @@ class ColorRelief(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['color-relief']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
arguments.append(self.parameterAsFile(parameters, self.COLOR_TABLE, context))

View File

@ -25,7 +25,8 @@ __copyright__ = '(C) 2012, Victor Olaya'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterFeatureSource,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterString,
QgsProcessingParameterEnum,
QgsProcessingParameterCrs,
@ -189,6 +190,9 @@ class OgrToPostGis(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
ogrLayer, layername = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
if not layername:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
shapeEncoding = self.parameterAsString(parameters, self.SHAPE_ENCODING, context)
ssrs = self.parameterAsCrs(parameters, self.S_SRS, context).authid()
tsrs = self.parameterAsCrs(parameters, self.T_SRS, context).authid()

View File

@ -27,7 +27,8 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsRasterFileWriter,
from qgis.core import (QgsProcessingException,
QgsRasterFileWriter,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -102,6 +103,8 @@ class aspect(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['aspect']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -126,6 +127,9 @@ class contour(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
fieldName = self.parameterAsString(parameters, self.FIELD_NAME, context)
if self.NODATA in parameters and parameters[self.NODATA] is not None:
nodata = self.parameterAsDouble(parameters, self.NODATA, context)

View File

@ -28,6 +28,7 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
QgsProcessingParameterNumber,
@ -116,7 +117,11 @@ class fillnodata(GdalAlgorithm):
arguments.append('-of')
arguments.append(QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1]))
arguments.append(self.parameterAsRasterLayer(parameters, self.INPUT, context).source())
raster = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if raster is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(raster.source())
arguments.append(out)
commands = []

View File

@ -26,7 +26,8 @@ __copyright__ = '(C) 2016, Médéric Ribreux'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterDefinition,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterCrs,
QgsProcessingParameterEnum,
@ -219,6 +220,9 @@ class gdal2tiles(GdalAlgorithm):
arguments.append('-n')
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
arguments.append(self.parameterAsString(parameters, self.OUTPUT, context))

View File

@ -26,6 +26,7 @@ __copyright__ = '(C) 2013, Alexander Bruy'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
QgsProcessingParameterBoolean,
@ -82,7 +83,11 @@ class gdal2xyz(GdalAlgorithm):
if self.parameterAsBool(parameters, self.CSV, context):
arguments.append('-csv')
arguments.append(self.parameterAsRasterLayer(parameters, self.INPUT, context).source())
raster = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if raster is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(raster.source())
arguments.append(self.parameterAsFileOutput(parameters, self.OUTPUT, context))
commands = []

View File

@ -29,7 +29,8 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsProcessingParameterRasterLayer,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterEnum,
QgsProcessingParameterString,
QgsProcessingParameterBoolean,
@ -110,6 +111,9 @@ class gdaladdo(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
fileName = inLayer.source()
arguments = []

View File

@ -28,7 +28,8 @@ __revision__ = '$Format:%H$'
import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsProcessingParameterRasterLayer,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBoolean,
QgsProcessingParameterFileDestination)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
@ -97,7 +98,11 @@ class gdalinfo(GdalAlgorithm):
arguments.append('-nogcp')
if self.parameterAsBool(parameters, self.NO_METADATA, context):
arguments.append('-nomd')
arguments.append(self.parameterAsRasterLayer(parameters, self.INPUT, context).source())
raster = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if raster is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(raster.source())
return [self.commandName(), GdalUtils.escapeAndJoin(arguments)]
def processAlgorithm(self, parameters, context, feedback):

View File

@ -29,6 +29,7 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -129,6 +130,9 @@ class hillshade(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['hillshade']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBoolean,
@ -97,6 +98,8 @@ class nearblack(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments = []
arguments.append(inLayer.source())

View File

@ -26,7 +26,8 @@ __copyright__ = '(C) 2012, Victor Olaya'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterVectorLayer,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterBoolean,
QgsProcessingParameterFileDestination)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
@ -81,6 +82,9 @@ class ogrinfo(GdalAlgorithm):
arguments.append('-nomd')
inLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
connectionString = GdalUtils.ogrConnectionString(inLayer.source(), context)
arguments.append(connectionString)
return arguments

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
QgsProcessingParameterBoolean,
@ -83,6 +84,9 @@ class pct2rgb(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = []
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -31,6 +31,7 @@ from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtCore import QFileInfo
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
QgsProcessingParameterString,
@ -91,6 +92,9 @@ class polygonize(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = []
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
outFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -136,6 +137,9 @@ class proximity(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
distance = self.parameterAsDouble(parameters, self.MAX_DISTANCE, context)
replaceValue = self.parameterAsDouble(parameters, self.REPLACE, context)
if self.NODATA in parameters and parameters[self.NODATA] is not None:

View File

@ -31,6 +31,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterNumber,
QgsProcessingParameterRasterDestination)
@ -87,7 +88,11 @@ class rgb2pct(GdalAlgorithm):
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
arguments.append('-of')
arguments.append(QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1]))
arguments.append(self.parameterAsRasterLayer(parameters, self.INPUT, context).source())
raster = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if raster is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(raster.source())
arguments.append(out)
if isWindows():

View File

@ -28,6 +28,7 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -91,6 +92,9 @@ class roughness(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['roughness']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterNumber,
QgsProcessingParameterBoolean,
@ -111,7 +112,11 @@ class sieve(GdalAlgorithm):
arguments.append('-of')
arguments.append(QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1]))
arguments.append(self.parameterAsRasterLayer(parameters, self.INPUT, context).source())
raster = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if raster is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(raster.source())
arguments.append(out)
commands = []

View File

@ -29,6 +29,7 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
@ -106,6 +107,9 @@ class slope(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['slope']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -28,7 +28,8 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsProcessingParameterDefinition,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
QgsProcessingParameterString,
@ -90,6 +91,9 @@ class tpi(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['TPI']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
arguments.append(out)

View File

@ -30,6 +30,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterNumber,
@ -115,6 +116,9 @@ class translate(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
if self.NODATA in parameters and parameters[self.NODATA] is not None:
nodata = self.parameterAsDouble(parameters, self.NODATA, context)

View File

@ -27,7 +27,8 @@ __revision__ = '$Format:%H$'
import os
from qgis.core import (QgsProcessingParameterDefinition,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterBand,
QgsProcessingParameterString,
@ -89,6 +90,9 @@ class tri(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = ['TRI']
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
arguments.append(inLayer.source())
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
arguments.append(out)

View File

@ -29,6 +29,7 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsRasterFileWriter,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterCrs,
@ -163,6 +164,9 @@ class warp(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
sourceCrs = self.parameterAsCrs(parameters, self.SOURCE_CRS, context)
targetCrs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)

View File

@ -52,7 +52,7 @@ from qgis.core import (QgsProcessingContext,
QgsPointXY,
QgsProject,
QgsRectangle,
QgsProcessingUtils,
QgsProcessingException,
QgsProcessingFeatureSourceDefinition)
import nose2
import os
@ -90,6 +90,18 @@ class TestGdalAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
for a in p.algorithms():
self.assertTrue(a.commandName(), 'Algorithm {} has no commandName!'.format(a.id()))
def testNoParameters(self):
# Test that algorithms throw QgsProcessingExceptions and not base Python
# exceptions when no parameters specified
p = QgsApplication.processingRegistry().providerById('gdal')
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
for a in p.algorithms():
try:
a.getConsoleCommands({}, context, feedback)
except QgsProcessingException:
pass
def testGetOgrCompatibleSourceFromMemoryLayer(self):
# create a memory layer and add to project and context
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",

View File

@ -30,7 +30,10 @@ import psycopg2.extensions # For isolation levels
import re
import os
from qgis.core import QgsDataSourceUri, QgsCredentials, QgsSettings
from qgis.core import (QgsProcessingException,
QgsDataSourceUri,
QgsCredentials,
QgsSettings)
from qgis.PyQt.QtCore import QCoreApplication
@ -44,7 +47,7 @@ def uri_from_name(conn_name):
settings.beginGroup(u"/PostgreSQL/connections/%s" % conn_name)
if not settings.contains("database"): # non-existent entry?
raise DbError(QCoreApplication.translate("PostGIS", 'There is no defined database connection "{0}".').format(conn_name))
raise QgsProcessingException(QCoreApplication.translate("PostGIS", 'There is no defined database connection "{0}".').format(conn_name))
uri = QgsDataSourceUri()
@ -126,19 +129,6 @@ class TableIndex(object):
self.columns = list(map(int, columns.split(' ')))
class DbError(Exception):
def __init__(self, message, query=None):
self.message = message
self.query = query
def __str__(self):
text = "MESSAGE: {}".format(self.message)
if self.query:
text = "{}\nQUERY: {}".format(text, self.query)
return text
class TableField(object):
def __init__(self, name, data_type, is_null=None, default=None,
@ -207,7 +197,7 @@ class GeoDB(object):
break
except psycopg2.OperationalError as e:
if i == 3:
raise DbError(str(e))
raise QgsProcessingException(str(e))
err = str(e)
user = self.uri.username()
@ -217,7 +207,7 @@ class GeoDB(object):
password,
err)
if not ok:
raise DbError(QCoreApplication.translate("PostGIS", 'Action canceled by user'))
raise QgsProcessingException(QCoreApplication.translate("PostGIS", 'Action canceled by user'))
if user:
self.uri.setUsername(user)
if password:
@ -823,8 +813,8 @@ class GeoDB(object):
try:
cursor.execute(sql)
except psycopg2.Error as e:
raise DbError(str(e),
e.cursor.query.decode(e.cursor.connection.encoding))
raise QgsProcessingException(str(e) + ' QUERY: ' +
e.cursor.query.decode(e.cursor.connection.encoding))
def _exec_sql_and_commit(self, sql):
"""Tries to execute and commit some action, on error it rolls