From d684c8c749ad937b52a305e6b2a1ae6de4b055b8 Mon Sep 17 00:00:00 2001 From: Hugo Mercier Date: Fri, 27 Mar 2015 14:32:41 +0100 Subject: [PATCH] [DBManager] Allow to load a layer without primary key --- .../plugins/db_manager/db_plugins/plugin.py | 15 ++++++++++++ .../db_plugins/spatialite/plugin.py | 2 ++ python/plugins/db_manager/dlg_sql_window.py | 11 ++++----- python/plugins/db_manager/ui/DlgSqlWindow.ui | 23 +++++++++++++++++-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/python/plugins/db_manager/db_plugins/plugin.py b/python/plugins/db_manager/db_plugins/plugin.py index 9630d402146..605e9c527a3 100644 --- a/python/plugins/db_manager/db_plugins/plugin.py +++ b/python/plugins/db_manager/db_plugins/plugin.py @@ -208,9 +208,24 @@ class Database(DbItemObject): return SqlResultModel(self, sql, parent) + def uniqueIdFunction(self): + """Return a SQL function used to generate a unique id for rows of a query""" + # may be overloaded by derived classes + return "row_number() over ()" + def toSqlLayer(self, sql, geomCol, uniqueCol, layerName="QueryLayer", layerType=None, avoidSelectById=False): from qgis.core import QgsMapLayer, QgsVectorLayer, QgsRasterLayer + if uniqueCol is None: + if hasattr(self, 'uniqueIdFunction'): + uniqueFct = self.uniqueIdFunction() + if uniqueFct is not None: + q = 1 + while "_subq_%d_" % q in sql: + q += 1 + sql = "SELECT %s AS _uid_,* FROM (%s) AS _subq_%d_" % (uniqueFct, sql, q) + uniqueCol = "_uid_" + uri = self.uri() uri.setDataSource("", u"(%s\n)" % sql, geomCol, "", uniqueCol) if avoidSelectById: diff --git a/python/plugins/db_manager/db_plugins/spatialite/plugin.py b/python/plugins/db_manager/db_plugins/spatialite/plugin.py index 12a6c3f4410..5855d11e55e 100644 --- a/python/plugins/db_manager/db_plugins/spatialite/plugin.py +++ b/python/plugins/db_manager/db_plugins/spatialite/plugin.py @@ -144,6 +144,8 @@ class SLDatabase(Database): return Database.runAction(self, action) + def uniqueIdFunction(self): + return None class SLTable(Table): def __init__(self, row, db, schema=None): diff --git a/python/plugins/db_manager/dlg_sql_window.py b/python/plugins/db_manager/dlg_sql_window.py index 057d05debde..2c7bee1e859 100644 --- a/python/plugins/db_manager/dlg_sql_window.py +++ b/python/plugins/db_manager/dlg_sql_window.py @@ -178,18 +178,17 @@ class DlgSqlWindow(QDialog, Ui_Dialog): QApplication.restoreOverrideCursor() def loadSqlLayer(self): - uniqueFieldName = self.uniqueCombo.currentText() + hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked + if hasUniqueField: + uniqueFieldName = self.uniqueCombo.currentText() + else: + uniqueFieldName = None hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked if hasGeomCol: geomFieldName = self.geomCombo.currentText() else: geomFieldName = None - if (hasGeomCol and geomFieldName == "") or uniqueFieldName == "": - QMessageBox.warning(self, self.tr("DB Manager"), self.tr( - "You must fill the required fields: \ngeometry column - column with unique integer values")) - return - query = self.editSql.text() if query == "": return diff --git a/python/plugins/db_manager/ui/DlgSqlWindow.ui b/python/plugins/db_manager/ui/DlgSqlWindow.ui index 36f13e8289f..8a9e378d297 100644 --- a/python/plugins/db_manager/ui/DlgSqlWindow.ui +++ b/python/plugins/db_manager/ui/DlgSqlWindow.ui @@ -6,7 +6,7 @@ 0 0 - 747 + 800 525 @@ -181,7 +181,7 @@ - + Column with unique integer values @@ -190,6 +190,9 @@ integer values + + false + 0 @@ -403,5 +406,21 @@ columns + + uniqueColumnCheck + toggled(bool) + uniqueCombo + setEnabled(bool) + + + 109 + 385 + + + 274 + 385 + + +