Экспорт шейп-файла в PostGIS через скрипт Python из QGIS

Sep 28 2020

Я разместил этот вопрос на StackOverFlow, где его рекомендовали разместить здесь.

Я хочу экспортировать шейп-файл в PostGIS с помощью скрипта Python из QGIS. Я использую QGIS 3.10, PostgreSQL 10 и PostGIS 2.5 в Windows 10. Я пробовал использовать qgis:importintopostgis:

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

Появляется сообщение об ошибке:

«.... При выполнении алгоритма произошли ошибки».

Интересно, что он работает с DB Manager, который, похоже, является графическим интерфейсом qgis:importintopostgis.

Различия, которые я вижу, - это SRID источника и цели. Я не знаю, как ввести эти параметры в qgis: importintopostgis. Я также не уверен, что мне нужно будет вводить имя пользователя и пароль для базы данных, но снова я не вижу, где вводить эти параметры qgis:importintopostgis.

Я также пробовал `gdal: importvectorintopostgisdatabaseavailableconnections:

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

Это выполняется без сообщения об ошибке, но также не импортирует таблицу в PostGIS. Что я делаю неправильно? Есть ли в QGIS метод, который работает с Python?

Привет @Jakob. Это работает. Спасибо.

Привет @DirkB: Я бегу:

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)

Затем я получаю следующее сообщение об ошибке:

Traceback (последний вызов последним): файл "C: \ PROGRA ~ 2 \ QGIS3 ~ 1.10 \ apps \ Python37 \ lib \ code.py", строка 90, в runcode exec (code, self.locals) File "", строка 1, в файле "", строка 98, в файле "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ tools \ general.py", строка 106, выполняется return Processing.runAlgorithm (algOrName, параметры, onFinish, обратная связь, контекст) Файл "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ core \ Processing.py", строка 181, в runAlgorithm вызывает исключение QgsProcessingException (msg) _core.QgsProcessingException: при выполнении алгоритма произошли ошибки.

Он создает таблицу в моей базе данных PostGIS. Но таблица пуста и содержит только поля «nummer» и «geom». Должен ли я определять поля где-нибудь в параметрах? Или мне нужно добавить в таблицу, в которой уже есть поля?

Я нашел Историю, это хорошо знать. Но он не регистрируется, когда я запускаю DB Manager. А другого плагина для импорта векторного слоя в PostGIS я не нашел. На какой из них вы ссылались?

Я нашел функцию сейчас на панели инструментов обработки. Я успешно запустил его и использовал текст из истории в Python. Через некоторое время появилось сообщение об ошибке «... При выполнении алгоритма произошли ошибки». Но он экспортировал таблицу в PostgreSQL. Количество функций правильное, и таблица пока выглядит неплохо. Так что я не совсем уверен, что на самом деле пошло не так.

Ответы

4 Jakob Sep 29 2020 at 14:42

Для записи. Пример функции Python, использующей OGR2OGR вне QGIS в OSGEO QGIS dist. Я использовал в поиске по диску 900 файлов форм в рекурсивных каталогах и загружал их в PostGIS без ошибок. Чтобы упростить код, я удалил некоторые имена таблиц GUID, чтобы избежать дублирования имен таблиц.

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

Вы уже были на правильном пути:

Чтобы экспортировать шейп-файл из QGIS 3 в PostGIS через pyqgis, вы можете использовать следующий код:

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)

Поскольку существует также плагин для импорта векторного слоя в PostGIS, вы можете выполнить его, а затем просмотреть код из History Protocol.

Плагин представляет собой плагин GDAL от Processing Toolbox «Экспорт в PostgreSQL (доступные соединения)»

Плагин выглядит следующим образом, и, вероятно, было бы проще сначала использовать его, а после проверки истории выполняемых процессов реализовать свой код.

Вот ссылка на документацию из QGIS 2 QGIS 2.6 docs

Вот ссылка на документацию по QGIS 3 QGIS 3.10 docs

Ваш код с:

 'GTYPE': 0

означает отсутствие типа геометрии, кстати. 5 будет многоугольником.

Более подробная информация о параметрах находится в ссылках на документацию QGIS 2 или QGIS 3.