28
28
from qgis .core import (QgsVectorLayerExporter ,
29
29
QgsSettings ,
30
30
QgsApplication ,
31
- QgsProcessingUtils )
31
+ QgsProcessingUtils ,
32
+ QgsProcessingParameterFeatureSource ,
33
+ QgsProcessingParameterString ,
34
+ QgsProcessingParameterField ,
35
+ QgsProcessingParameterBoolean ,
36
+ QgsWkbTypes )
32
37
33
38
from processing .algs .qgis .QgisAlgorithm import QgisAlgorithm
34
39
from processing .core .GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
@@ -65,49 +70,52 @@ def group(self):
65
70
66
71
def __init__ (self ):
67
72
super ().__init__ ()
68
- self .addParameter (ParameterVector (self .INPUT ,
69
- self .tr ('Layer to import' )))
70
- self .addParameter (ParameterString (
73
+ self .addParameter (QgsProcessingParameterFeatureSource (self .INPUT ,
74
+ self .tr ('Layer to import' )))
75
+
76
+ db_param = QgsProcessingParameterString (
71
77
self .DATABASE ,
72
- self .tr ('Database (connection name)' ),
73
- metadata = {
74
- 'widget_wrapper' : {
75
- 'class' : 'processing.gui.wrappers_postgis.ConnectionWidgetWrapper' }}))
76
- self .addParameter (ParameterString (
78
+ self .tr ('Database (connection name)' ))
79
+ db_param .setMetadata ({
80
+ 'widget_wrapper' : {
81
+ 'class' : 'processing.gui.wrappers_postgis.ConnectionWidgetWrapper' }})
82
+ self .addParameter (db_param )
83
+
84
+ schema_param = QgsProcessingParameterString (
77
85
self .SCHEMA ,
78
- self .tr ('Schema (schema name)' ),
79
- 'public' ,
80
- optional = True ,
81
- metadata = {
82
- 'widget_wrapper ' : {
83
- 'class' : 'processing.gui.wrappers_postgis.SchemaWidgetWrapper' ,
84
- 'connection_param' : self . DATABASE }}))
85
- self . addParameter ( ParameterString (
86
+ self .tr ('Schema (schema name)' ), 'public' , False , True )
87
+ schema_param . setMetadata ({
88
+ 'widget_wrapper' : {
89
+ 'class' : 'processing.gui.wrappers_postgis.SchemaWidgetWrapper' ,
90
+ 'connection_param ' : self . DATABASE }})
91
+ self . addParameter ( schema_param )
92
+
93
+ table_param = QgsProcessingParameterString (
86
94
self .TABLENAME ,
87
- self .tr ('Table to import to (leave blank to use layer name)' ),
88
- '' ,
89
- optional = True ,
90
- metadata = {
91
- 'widget_wrapper ' : {
92
- 'class' : 'processing.gui.wrappers_postgis.TableWidgetWrapper' ,
93
- 'schema_param' : self . SCHEMA }}))
94
- self .addParameter (ParameterTableField (self .PRIMARY_KEY ,
95
- self .tr ('Primary key field' ), self .INPUT , optional = True ))
96
- self .addParameter (ParameterString (self .GEOMETRY_COLUMN ,
97
- self .tr ('Geometry column' ), 'geom' ))
98
- self .addParameter (ParameterString (self .ENCODING ,
99
- self .tr ('Encoding' ), 'UTF-8' ,
100
- optional = True ))
101
- self .addParameter (ParameterBoolean (self .OVERWRITE ,
102
- self .tr ('Overwrite' ), True ))
103
- self .addParameter (ParameterBoolean (self .CREATEINDEX ,
104
- self .tr ('Create spatial index' ), True ))
105
- self .addParameter (ParameterBoolean (self .LOWERCASE_NAMES ,
106
- self .tr ('Convert field names to lowercase' ), True ))
107
- self .addParameter (ParameterBoolean (self .DROP_STRING_LENGTH ,
108
- self .tr ('Drop length constraints on character fields' ), False ))
109
- self .addParameter (ParameterBoolean (self .FORCE_SINGLEPART ,
110
- self .tr ('Create single-part geometries instead of multi-part' ), False ))
95
+ self .tr ('Table to import to (leave blank to use layer name)' ), '' , False , True )
96
+ table_param . setMetadata ({
97
+ 'widget_wrapper' : {
98
+ 'class' : 'processing.gui.wrappers_postgis.TableWidgetWrapper' ,
99
+ 'schema_param ' : self . SCHEMA }})
100
+ self . addParameter ( table_param )
101
+
102
+ self .addParameter (QgsProcessingParameterField (self .PRIMARY_KEY ,
103
+ self .tr ('Primary key field' ), None , self .INPUT , QgsProcessingParameterField . Any , False , True ))
104
+ self .addParameter (QgsProcessingParameterString (self .GEOMETRY_COLUMN ,
105
+ self .tr ('Geometry column' ), 'geom' ))
106
+ self .addParameter (QgsProcessingParameterString (self .ENCODING ,
107
+ self .tr ('Encoding' ), 'UTF-8' ,
108
+ False , True ))
109
+ self .addParameter (QgsProcessingParameterBoolean (self .OVERWRITE ,
110
+ self .tr ('Overwrite' ), True ))
111
+ self .addParameter (QgsProcessingParameterBoolean (self .CREATEINDEX ,
112
+ self .tr ('Create spatial index' ), True ))
113
+ self .addParameter (QgsProcessingParameterBoolean (self .LOWERCASE_NAMES ,
114
+ self .tr ('Convert field names to lowercase' ), True ))
115
+ self .addParameter (QgsProcessingParameterBoolean (self .DROP_STRING_LENGTH ,
116
+ self .tr ('Drop length constraints on character fields' ), False ))
117
+ self .addParameter (QgsProcessingParameterBoolean (self .FORCE_SINGLEPART ,
118
+ self .tr ('Create single-part geometries instead of multi-part' ), False ))
111
119
112
120
def name (self ):
113
121
return 'importintopostgis'
@@ -116,22 +124,21 @@ def displayName(self):
116
124
return self .tr ('Import into PostGIS' )
117
125
118
126
def processAlgorithm (self , parameters , context , feedback ):
119
- connection = self .getParameterValue ( self .DATABASE )
127
+ connection = self .parameterAsString ( parameters , self .DATABASE , context )
120
128
db = postgis .GeoDB .from_name (connection )
121
129
122
- schema = self .getParameterValue ( self .SCHEMA )
123
- overwrite = self .getParameterValue ( self .OVERWRITE )
124
- createIndex = self .getParameterValue ( self .CREATEINDEX )
125
- convertLowerCase = self .getParameterValue ( self .LOWERCASE_NAMES )
126
- dropStringLength = self .getParameterValue ( self .DROP_STRING_LENGTH )
127
- forceSinglePart = self .getParameterValue ( self .FORCE_SINGLEPART )
128
- primaryKeyField = self .getParameterValue ( self .PRIMARY_KEY ) or 'id'
129
- encoding = self .getParameterValue ( self .ENCODING )
130
+ schema = self .parameterAsString ( parameters , self .SCHEMA , context )
131
+ overwrite = self .parameterAsBool ( parameters , self .OVERWRITE , context )
132
+ createIndex = self .parameterAsBool ( parameters , self .CREATEINDEX , context )
133
+ convertLowerCase = self .parameterAsBool ( parameters , self .LOWERCASE_NAMES , context )
134
+ dropStringLength = self .parameterAsBool ( parameters , self .DROP_STRING_LENGTH , context )
135
+ forceSinglePart = self .parameterAsBool ( parameters , self .FORCE_SINGLEPART , context )
136
+ primaryKeyField = self .parameterAsString ( parameters , self .PRIMARY_KEY , context ) or 'id'
137
+ encoding = self .parameterAsString ( parameters , self .ENCODING , context )
130
138
131
- layerUri = self .getParameterValue (self .INPUT )
132
- layer = QgsProcessingUtils .mapLayerFromString (layerUri , context )
139
+ source = self .parameterAsSource (parameters , self .INPUT , context )
133
140
134
- table = self .getParameterValue ( self .TABLENAME )
141
+ table = self .parameterAsString ( parameters , self .TABLENAME , context )
135
142
if table :
136
143
table .strip ()
137
144
if not table or table == '' :
@@ -140,9 +147,9 @@ def processAlgorithm(self, parameters, context, feedback):
140
147
table = table .replace (' ' , '' ).lower ()[0 :62 ]
141
148
providerName = 'postgres'
142
149
143
- geomColumn = self .getParameterValue ( self .GEOMETRY_COLUMN )
150
+ geomColumn = self .parameterAsString ( parameters , self .GEOMETRY_COLUMN , context )
144
151
if not geomColumn :
145
- geomColumn = 'the_geom '
152
+ geomColumn = 'geom '
146
153
147
154
options = {}
148
155
if overwrite :
@@ -156,32 +163,45 @@ def processAlgorithm(self, parameters, context, feedback):
156
163
options ['forceSinglePartGeometryType' ] = True
157
164
158
165
# Clear geometry column for non-geometry tables
159
- if not layer . hasGeometryType () :
166
+ if source . wkbType () == QgsWkbTypes . NoGeometry :
160
167
geomColumn = None
161
168
162
169
uri = db .uri
163
170
uri .setDataSource (schema , table , geomColumn , '' , primaryKeyField )
164
171
165
172
if encoding :
166
- layer .setProviderEncoding (encoding )
167
-
168
- (ret , errMsg ) = QgsVectorLayerExporter .exportLayer (
169
- layer ,
170
- uri .uri (),
171
- providerName ,
172
- self .crs ,
173
- False ,
174
- options ,
175
- )
176
- if ret != 0 :
173
+ options ['fileEncoding' ] = encoding
174
+
175
+ exporter = QgsVectorLayerExporter (uri .uri (), providerName , source .fields (),
176
+ source .wkbType (), source .sourceCrs (), overwrite , options )
177
+
178
+ if exporter .errorCode () != QgsVectorLayerExporter .NoError :
179
+ raise GeoAlgorithmExecutionException (
180
+ self .tr ('Error importing to PostGIS\n {0}' ).format (exporter .errorMessage ()))
181
+
182
+ features = source .getFeatures ()
183
+ total = 100.0 / source .featureCount ()
184
+ for current , f in enumerate (features ):
185
+ if feedback .isCanceled ():
186
+ break
187
+
188
+ if not exporter .addFeature (f ):
189
+ feedback .reportError (exporter .errorMessage ())
190
+
191
+ feedback .setProgress (int (current * total ))
192
+
193
+ exporter .flushBuffer ()
194
+ if exporter .errorCode () != QgsVectorLayerExporter .NoError :
177
195
raise GeoAlgorithmExecutionException (
178
- self .tr ('Error importing to PostGIS\n {0}' ).format (errMsg ))
196
+ self .tr ('Error importing to PostGIS\n {0}' ).format (exporter . errorMessage () ))
179
197
180
198
if geomColumn and createIndex :
181
199
db .create_spatial_index (table , schema , geomColumn )
182
200
183
201
db .vacuum_analyze (table , schema )
184
202
203
+ return {}
204
+
185
205
def dbConnectionNames (self ):
186
206
settings = QgsSettings ()
187
207
settings .beginGroup ('/PostgreSQL/connections/' )
0 commit comments