Skip to content

Commit e2c2575

Browse files
committedMay 21, 2014
Merge pull request #1375 from nyalldawson/processing_postgis2
Some postgresql provider and PostGIS-related processing improvements and fixes (v2)
2 parents 6df9d1c + ec3da40 commit e2c2575

File tree

3 files changed

+55
-16
lines changed

3 files changed

+55
-16
lines changed
 

‎python/plugins/processing/algs/admintools/ImportIntoPostGIS.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from processing.parameters.ParameterVector import ParameterVector
3737
from processing.parameters.ParameterString import ParameterString
3838
from processing.parameters.ParameterSelection import ParameterSelection
39+
from processing.parameters.ParameterTableField import ParameterTableField
3940
from processing.tools import dataobjects
4041
import postgis_utils
4142

@@ -50,6 +51,8 @@ class ImportIntoPostGIS(GeoAlgorithm):
5051
CREATEINDEX = 'CREATEINDEX'
5152
GEOMETRY_COLUMN = 'GEOMETRY_COLUMN'
5253
LOWERCASE_NAMES = 'LOWERCASE_NAMES'
54+
DROP_STRING_LENGTH = 'DROP_STRING_LENGTH'
55+
PRIMARY_KEY = 'PRIMARY_KEY'
5356

5457
def getIcon(self):
5558
return QIcon(os.path.dirname(__file__) + '/../../images/postgis.png')
@@ -60,6 +63,8 @@ def processAlgorithm(self, progress):
6063
overwrite = self.getParameterValue(self.OVERWRITE)
6164
createIndex = self.getParameterValue(self.CREATEINDEX)
6265
convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES)
66+
dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH)
67+
primaryKeyField = self.getParameterValue(self.PRIMARY_KEY)
6368
settings = QSettings()
6469
mySettings = '/PostgreSQL/connections/' + connection
6570
try:
@@ -87,15 +92,22 @@ def processAlgorithm(self, progress):
8792
if not geomColumn:
8893
geomColumn = 'the_geom'
8994

90-
uri = QgsDataSourceURI()
91-
uri.setConnection(host, str(port), database, username, password)
92-
uri.setDataSource(schema, table, geomColumn, '')
93-
9495
options = {}
9596
if overwrite:
9697
options['overwrite'] = True
9798
if convertLowerCase:
9899
options['lowercaseFieldNames'] = True
100+
geomColumn = geomColumn.lower()
101+
if dropStringLength:
102+
options['dropStringConstraints'] = True
103+
104+
uri = QgsDataSourceURI()
105+
uri.setConnection(host, str(port), database, username, password)
106+
if primaryKeyField:
107+
uri.setDataSource(schema, table, geomColumn, '', primaryKeyField)
108+
else:
109+
uri.setDataSource(schema, table, geomColumn, '')
110+
99111
layerUri = self.getParameterValue(self.INPUT)
100112
layer = dataobjects.getObjectFromUri(layerUri)
101113
(ret, errMsg) = QgsVectorLayerImport.importLayer(
@@ -133,10 +145,14 @@ def defineCharacteristics(self):
133145
self.addParameter(ParameterString(self.SCHEMA, 'Schema (schema name)'))
134146
self.addParameter(ParameterString(self.TABLENAME, 'Table to import to'
135147
))
148+
self.addParameter(ParameterTableField(self.PRIMARY_KEY, 'Primary key field',
149+
self.INPUT, optional=True))
136150
self.addParameter(ParameterString(self.GEOMETRY_COLUMN, 'Geometry column', 'the_geom'
137151
))
138152
self.addParameter(ParameterBoolean(self.OVERWRITE, 'Overwrite', True))
139153
self.addParameter(ParameterBoolean(self.CREATEINDEX,
140154
'Create spatial index', True))
141155
self.addParameter(ParameterBoolean(self.LOWERCASE_NAMES,
142156
'Convert field names to lowercase', False))
157+
self.addParameter(ParameterBoolean(self.DROP_STRING_LENGTH,
158+
'Drop length constraints on character fields', False))

‎src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,9 +2767,17 @@ bool QgsPostgresProvider::getGeometryDetails()
27672767
return mValid;
27682768
}
27692769

2770-
bool QgsPostgresProvider::convertField( QgsField &field )
2770+
bool QgsPostgresProvider::convertField( QgsField &field , const QMap<QString, QVariant>* options )
27712771
{
2772-
QString fieldType = "varchar"; //default to string
2772+
//determine field type to use for strings
2773+
QString stringFieldType = "varchar";
2774+
if ( options->contains( "dropStringConstraints" ) && options->value( "dropStringConstraints" ).toBool() )
2775+
{
2776+
//drop string length constraints by using PostgreSQL text type for strings
2777+
stringFieldType = "text";
2778+
}
2779+
2780+
QString fieldType = stringFieldType; //default to string
27732781
int fieldSize = field.length();
27742782
int fieldPrec = field.precision();
27752783
switch ( field.type() )
@@ -2788,7 +2796,7 @@ bool QgsPostgresProvider::convertField( QgsField &field )
27882796
break;
27892797

27902798
case QVariant::String:
2791-
fieldType = "varchar";
2799+
fieldType = stringFieldType;
27922800
fieldPrec = -1;
27932801
break;
27942802

@@ -2900,7 +2908,7 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
29002908
{
29012909
// found, get the field type
29022910
QgsField fld = fields[fldIdx];
2903-
if ( convertField( fld ) )
2911+
if ( convertField( fld, options ) )
29042912
{
29052913
primaryKeyType = fld.typeName();
29062914
}
@@ -2953,6 +2961,13 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
29532961
throw PGException( result );
29542962
}
29552963

2964+
if ( options->contains( "lowercaseFieldNames" ) && options->value( "lowercaseFieldNames" ).toBool() )
2965+
{
2966+
//convert primary key name to lowercase
2967+
//this must happen after determining the field type of the primary key
2968+
primaryKey = primaryKey.toLower();
2969+
}
2970+
29562971
sql = QString( "CREATE TABLE %1(%2 %3 PRIMARY KEY)" )
29572972
.arg( schemaTableName )
29582973
.arg( quotedIdentifier( primaryKey ) )
@@ -3032,14 +3047,11 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
30323047
for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
30333048
{
30343049
QgsField fld = fields[fldIdx];
3035-
if ( fld.name() == primaryKey )
3036-
{
3037-
oldToNewAttrIdxMap->insert( fldIdx, 0 );
3038-
continue;
3039-
}
30403050

30413051
if ( fld.name() == geometryColumn )
30423052
{
3053+
//the "lowercaseFieldNames" option does not affect the name of the geometry column, so we perform
3054+
//this test before converting the field name to lowercase
30433055
QgsDebugMsg( "Found a field with the same name of the geometry column. Skip it!" );
30443056
continue;
30453057
}
@@ -3050,7 +3062,13 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
30503062
fld.setName( fld.name().toLower() );
30513063
}
30523064

3053-
if ( !convertField( fld ) )
3065+
if ( fld.name() == primaryKey )
3066+
{
3067+
oldToNewAttrIdxMap->insert( fldIdx, 0 );
3068+
continue;
3069+
}
3070+
3071+
if ( !convertField( fld, options ) )
30543072
{
30553073
if ( errorMessage )
30563074
*errorMessage = QObject::tr( "Unsupported type for field %1" ).arg( fld.name() );

‎src/providers/postgres/qgspostgresprovider.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ class QgsPostgresProvider : public QgsVectorDataProvider
4747

4848
public:
4949

50-
/** Import a vector layer into the database */
50+
/** Import a vector layer into the database
51+
* @param options options for provider, specified via a map of option name
52+
* to value. Valid options are lowercaseFieldNames (set to true to convert
53+
* field names to lowercase), dropStringConstraints (set to true to remove
54+
* length constraints on character fields).
55+
*/
5156
static QgsVectorLayerImport::ImportError createEmptyLayer(
5257
const QString& uri,
5358
const QgsFields &fields,
@@ -324,7 +329,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
324329
bool loadFields();
325330

326331
/** convert a QgsField to work with PG */
327-
static bool convertField( QgsField &field );
332+
static bool convertField( QgsField &field, const QMap<QString, QVariant> *options = 0 );
328333

329334
/**Parses the enum_range of an attribute and inserts the possible values into a stringlist
330335
@param enumValues the stringlist where the values are appended

0 commit comments

Comments
 (0)
Please sign in to comment.