Esportare shapefile in PostGIS tramite script Python da QGIS

Sep 28 2020

Ho pubblicato questa domanda su StackOverFlow dove è stato consigliato di pubblicarla piuttosto qui.

Voglio esportare uno shapefile in PostGIS tramite uno script Python da QGIS. Sto usando QGIS 3.10, PostgreSQL 10 e PostGIS 2.5 su Windows 10. Ho provato a usare qgis:importintopostgis:

import processing
processing.run("qgis:importintopostgis",{
                'INPUT': 'unioncrs',
                'DATABASE': "HistoPG",
                'SCHEMA': "public",
                'TABLENAME': "testunion",
                'PRIMARY_KEY': "Nummer"
                })

Ciò produce un messaggio di errore:

".... Si sono verificati errori durante l'esecuzione dell'algoritmo."

È interessante notare che funziona con DB Manager, che sembra essere una GUI di qgis:importintopostgis.

Le differenze che posso vedere sono l'origine e gli SRID di destinazione. Non so come inserire questi parametri in qgis: importintopostgis. Inoltre, non sono sicuro di non aver bisogno di inserire nome utente e password per il database, ma ancora una volta non vedo dove inserire questi parametri qgis:importintopostgis.

Ho anche provato `gdal: importvectorintopostgisdatabaseavailableconnections:

processing.run("gdal:importvectorintopostgisdatabaseavailableconnections",{
                'DATABASE': "HistoPG",
                'INPUT': 'C:/QGIS/Vers1/Results/unioncrs.shp',
                'GTYPE': 0,
                'SCHEMA': "public",
                'TABLE': "testunion"
                })

Funziona senza messaggi di errore ma non importa nemmeno una tabella in PostGIS. Che cosa sto facendo di sbagliato? Esiste un metodo che funziona con Python di QGIS?

Ciao @Jakob. Che funzioni. Grazie.

Ciao @DirkB: corro:

PARAMETERS = {'DATABASE':'HistoPG','INPUT':'C:\\QGIS\\Vers1\\Results\\unioncrs.shp', 
'SHAPE_ENCODING':'utf-8','GTYPE':0,'A_SRS':QgsCoordinateReferenceSystem('EPSG:31467'),'T_SRS':None,'S_SRS':None,
    'SCHEMA':'public','TABLE':'testunion','PK':'Nummer','PRIMARY_KEY':'','GEOCOLUMN':'geom','DIM':0,'SIMPLIFY':'',
   'SEGMENTIZE':'','SPAT':None,'CLIP':False,'WHERE':'','GT':'','OVERWRITE':True,'APPEND':False,
    'ADDFIELDS':False,'LAUNDER':False,'INDEX':False,'SKIPFAILURES':False,'PROMOTETOMULTI':True,
    'PRECISION':True,'OPTIONS':''}

processing.run("gdal:importvectorintopostgisdatabaseavailableconnections", PARAMETERS)

Quindi ricevo il seguente messaggio di errore:

Traceback (la chiamata più recente per ultima): File "C: \ PROGRA ~ 2 \ QGIS3 ~ 1.10 \ apps \ Python37 \ lib \ code.py", riga 90, in runcode exec (code, self.locals) File "", riga 1, in File "", riga 98, in File "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ tools \ general.py", riga 106, in esecuzione return Processing.runAlgorithm (algOrName, parameters, onFinish, feedback, context) File "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ core \ Processing.py", riga 181, in runAlgorithm raise QgsProcessingException (msg) _core.QgsProcessingException: si sono verificati errori durante l'esecuzione dell'algoritmo.

Crea una tabella nel mio database PostGIS. Ma la tabella è vuota e ha solo i campi "nummer" e "geom". Devo definire i campi da qualche parte nei parametri? O devo aggiungere a una tabella che ha già i campi?

Ho trovato la Storia, buono a sapersi. Ma non viene registrato quando eseguo DB Manager. E non ho trovato nessun altro plugin per importare un livello vettoriale in PostGIS. A quale ti riferivi?

Ho trovato la funzione ora nella casella degli strumenti di elaborazione. L'ho eseguito con successo e ho utilizzato il testo della cronologia in Python. Ciò ha prodotto dopo un po 'un messaggio di errore "... Si sono verificati errori durante l'esecuzione dell'algoritmo." Ma aveva esportato la tabella in PostgreSQL. Il numero di funzioni è corretto e la tabella sembra a posto finora. Quindi non sono abbastanza sicuro di cosa sia andato storto in realtà.

Risposte

4 Jakob Sep 29 2020 at 14:42

Per il record. Un esempio di una funzione Python che utilizza OGR2OGR al di fuori di QGIS di un OSGEO QGIS dist. Ho usato in una passeggiata su disco trovando 900 file di forma in directory ricorsive e caricati su PostGIS senza errori. Per semplificare il codice ho rimosso alcuni nomi di tabelle GUID per evitare nomi di tabelle duplicati.

def upload_to_db(shpfile):
    """
    Uploades shape files to PostgreSQL with org2ogr
    :param shpfile: Shapefile to upload to database
    :return: None
    """

    dbname = 'mydb'
    schema = 'myschema'
    host = 'xx.xx.xxx.xx'
    user = 'myuser'
    password = 'mypw'
    port = '5432'

    tablename = f'{os.path.basename(shpfile)}'

    # https://gdal.org/drivers/vector/pg.html
    command = f"""SET PGCLIENTENCODING=LATIN1 && ogr2ogr -f "PostgreSQL" PG:"host={host} dbname={dbname} user={user} password={password} port={port}" "{shpfile}" -nln {schema}.{tablename} -lco geometry_name=geom -lco precision=NO -nlt promote_to_multi -a_srs epsg:25832"""

    #print(command)
    os.system(command)
4 DirkB. Sep 28 2020 at 16:58

Eri già sulla strada giusta:

Per esportare uno shapefile da QGIS 3 a PostGIS tramite pyqgis puoi usare il seguente codice:

import processing
PARAMETERS = {'DATABASE':'nameofdatabase','INPUT':'C:\\Users\\yourpath\\shapename.shp|layername=shapename',
    'SHAPE_ENCODING':'utf-8','GTYPE':5,'A_SRS':QgsCoordinateReferenceSystem('EPSG:4326'),'T_SRS':None,'S_SRS':None,
    'SCHEMA':'schemaname','TABLE':'filenameinpostgis','PK':'id','PRIMARY_KEY':'','GEOCOLUMN':'geom','DIM':0,'SIMPLIFY':'',
    'SEGMENTIZE':'','SPAT':None,'CLIP':False,'WHERE':'','GT':'','OVERWRITE':True,'APPEND':False,
    'ADDFIELDS':False,'LAUNDER':False,'INDEX':False,'SKIPFAILURES':False,'PROMOTETOMULTI':True,
    'PRECISION':True,'OPTIONS':''}

processing.run("gdal:importvectorintopostgisdatabaseavailableconnections", PARAMETERS)

Poiché esiste anche un plug-in per importare il livello vettoriale in PostGIS, puoi eseguirlo e quindi vedere il codice da History Protocol.

Il plugin è il plugin GDAL di Processing Toolbox "Export to PostgreSQL (connessioni disponibili)"

Il plugin ha l'aspetto seguente e probabilmente sarebbe più facile usarlo prima e dopo aver controllato la cronologia dei processi eseguiti, implementare il codice.

Ecco un collegamento alla documentazione dai documenti di QGIS 2 QGIS 2.6

Ecco un collegamento alla documentazione per QGIS 3 QGIS 3.10 docs

Il tuo codice con:

 'GTYPE': 0

significa nessun tipo di geometria btw. 5 sarebbe un poligono.

Maggiori informazioni sono nei collegamenti alla documentazione di QGIS 2 o QGIS 3 sui parametri.