Exportando shapefile para PostGIS via script Python do QGIS

Sep 28 2020

Eu postei esta pergunta no StackOverFlow onde foi recomendado postá-la aqui.

Quero exportar um arquivo de forma para PostGIS por meio de um script Python do QGIS. Estou usando QGIS 3.10, PostgreSQL 10 e PostGIS 2.5 no Windows 10. Tentei usar qgis:importintopostgis:

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

Isso produz uma mensagem de erro:

“.... Ocorreram erros ao executar o algoritmo.”

Curiosamente, ele funciona com o DB Manager, que parece ser uma GUI do qgis:importintopostgis.

As diferenças que posso ver são os SRIDs de origem e de destino. Não sei como inserir esses parâmetros no qgis: importintopostgis. Também não tenho certeza se não precisaria inserir o nome de usuário e a senha no banco de dados, mas, novamente, não vejo onde inserir esses parâmetros qgis:importintopostgis.

Eu também tentei `gdal: importvectorintopostgisdatabaseavailableconnections:

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

Isso é executado sem mensagem de erro, mas também não importa uma tabela para PostGIS. O que estou fazendo errado? Existe um método que funciona com Python do QGIS?

Olá, @Jakob. Isso funciona. Obrigado.

Olá @DirkB: Eu executo:

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)

Então, recebo a seguinte mensagem de erro:

Traceback (última chamada mais recente): Arquivo "C: \ PROGRA ~ 2 \ QGIS3 ~ 1.10 \ apps \ Python37 \ lib \ code.py", linha 90, em runcode exec (code, self.locals) Arquivo "", linha 1, no Arquivo "", linha 98, no Arquivo "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ tools \ general.py", linha 106, em execução return Processing.runAlgorithm (algOrName, parameters, onFinish, feedback, context) Arquivo "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ core \ Processing.py", linha 181, em runAlgorithm, aumente QgsProcessingException (msg) _core.QgsProcessingException: Houve erros ao executar o algoritmo.

Ele cria uma tabela em meu banco de dados PostGIS. Mas a tabela está vazia e contém apenas os campos ‚nummer 'e‚ geom'. Devo definir os campos em algum lugar dos parâmetros? Ou tenho que acrescentar a uma tabela que já contém os campos?

Encontrei a História, é bom saber. Mas não registra quando executo o DB Manager. E não encontrei nenhum outro plugin para importar uma camada vetorial para o PostGIS. A qual você se referiu?

Encontrei a função agora na caixa de ferramentas de processamento. Eu executei com sucesso e usei o texto da história em Python. Isso produziu depois de um tempo uma mensagem de erro „... Houve erros ao executar o algoritmo.“ Mas a tabela foi exportada para o PostgreSQL. O número de recursos está correto e a tabela parece boa até agora. Portanto, não tenho certeza do que realmente deu errado.

Respostas

4 Jakob Sep 29 2020 at 14:42

Para registro. Um exemplo de uma função Python usando OGR2OGR fora do QGIS de um dist do OSGEO QGIS. Eu usei em uma caminhada de disco para encontrar 900 arquivos de forma em diretórios recursivos e carreguei para PostGIS sem erros. Para simplificar o código, removi alguns nomes de tabelas GUID para evitar nomes de tabelas 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)
4 DirkB. Sep 28 2020 at 16:58

Você já estava no caminho certo:

Para exportar um Shapefile de QGIS 3 para PostGIS por meio de pyqgis, você pode usar o seguinte 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)

Como também existe um Plugin para importar a camada vetorial para PostGIS, você pode executá-lo e ver o código do History Protocol.

O plugin é o plugin GDAL da caixa de ferramentas de processamento "Exportar para PostgreSQL (conexões disponíveis)"

O plug-in se parece com o seguinte, e provavelmente seria mais fácil usá-lo primeiro e depois de verificar o histórico de processos executados, implemente seu código.

Aqui está um link para a documentação do QGIS 2 QGIS 2.6 docs

Aqui está um link para a documentação do QGIS 3 QGIS 3.10 docs

Seu código com:

 'GTYPE': 0

significa nenhum tipo de geometria aliás. 5 seria um polígono.

Mais informações estão nos links para a documentação do QGIS 2 ou QGIS 3 sobre parâmetros.