Exportar shapefile a PostGIS a través de un script de Python desde QGIS
Publiqué esta pregunta en StackOverFlow donde se recomendó publicarla aquí.
Quiero exportar un shapefile a PostGIS a través de un script de Python desde QGIS. Estoy usando QGIS 3.10, PostgreSQL 10 y PostGIS 2.5 en Windows 10. Intenté usar qgis:importintopostgis:
import processing
processing.run("qgis:importintopostgis",{
'INPUT': 'unioncrs',
'DATABASE': "HistoPG",
'SCHEMA': "public",
'TABLENAME': "testunion",
'PRIMARY_KEY': "Nummer"
})
Eso produce un mensaje de error:
".... Hubo errores al ejecutar el algoritmo".
Curiosamente, funciona con DB Manager, que parece ser una GUI de qgis:importintopostgis.
Las diferencias que puedo ver son los SRID de origen y de destino. No sé cómo ingresar estos parámetros en qgis: importintopostgis. Tampoco estoy seguro de si no necesitaría ingresar el nombre de usuario y la contraseña para la base de datos, pero nuevamente no veo dónde ingresar estos parámetros qgis:importintopostgis.
También probé `gdal: importvectorintopostgisdatabaseavailableconnections:
processing.run("gdal:importvectorintopostgisdatabaseavailableconnections",{
'DATABASE': "HistoPG",
'INPUT': 'C:/QGIS/Vers1/Results/unioncrs.shp',
'GTYPE': 0,
'SCHEMA': "public",
'TABLE': "testunion"
})
Eso se ejecuta sin mensaje de error, pero tampoco importa una tabla a PostGIS. ¿Qué estoy haciendo mal? ¿Existe algún método que funcione con Python de QGIS?
Hola @Jakob. Eso funciona. Gracias.
Hola @DirkB: yo 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)
Luego recibo el siguiente mensaje de error:
Traceback (última llamada más reciente): Archivo "C: \ PROGRA ~ 2 \ QGIS3 ~ 1.10 \ apps \ Python37 \ lib \ code.py", línea 90, en runcode exec (código, self.locals) Archivo "", línea 1, en el Archivo "", línea 98, en el Archivo "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ tools \ general.py", línea 106, en ejecución return Processing.runAlgorithm (algOrName, parámetros, onFinish, feedback, context) Archivo "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ core \ Processing.py", línea 181, en runAlgorithm raise QgsProcessingException (msg) _core.QgsProcessingException: Hubo errores al ejecutar el algoritmo.
Crea una tabla en mi base de datos PostGIS. Pero la tabla está vacía y solo tiene los campos "nummer" y "geom". ¿Tengo que definir los campos en algún lugar de los parámetros? ¿O tengo que agregar a una tabla que ya tiene los campos?
Encontré la Historia, es bueno saberlo. Pero no se registra cuando ejecuto DB Manager. Y no encontré ningún otro complemento para importar una capa vectorial en PostGIS. ¿A cuál te refieres?
Encontré la función ahora en la caja de herramientas de Procesamiento. Lo ejecuté con éxito y usé el texto del historial en Python. Eso produjo después de un tiempo un mensaje de error "... Hubo errores al ejecutar el algoritmo". Pero había exportado la tabla a PostgreSQL. El número de funciones es correcto y la tabla se ve bien hasta ahora. Así que no estoy muy seguro de qué salió mal en realidad.
Respuestas
Para el registro. Un ejemplo de una función de Python que usa OGR2OGR fuera de QGIS de un dist de OSGEO QGIS. Usé en un paseo por el disco para encontrar 900 archivos de formas en directorios recursivos y los cargué en PostGIS sin error. Para simplificar el código, eliminé algunos nombres de tablas GUID para evitar nombres de tablas duplicados.
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)
Ya estabas en el camino correcto:
Para exportar un Shapefile de QGIS 3 a PostGIS a través de pyqgis, puede usar el siguiente código:
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)
Dado que también hay un complemento para importar la capa vectorial en PostGIS, puede ejecutarlo y luego ver el código del Protocolo de historial.
El complemento es el complemento GDAL de Processing Toolbox "Exportar a PostgreSQL (conexiones disponibles)"
El complemento parece el siguiente, y probablemente sería más fácil usarlo primero y después de verificar el Historial de procesos ejecutados, implemente su código.
Aquí hay un enlace a la documentación de QGIS 2 QGIS 2.6 docs
Aquí hay un enlace a la documentación de QGIS 3 QGIS 3.10 docs
Tu código con:
'GTYPE': 0
significa que no hay tipo de geometría por cierto. 5 sería polígono.
Hay más información en los enlaces a la documentación de QGIS 2 o QGIS 3 sobre parámetros.