Экспорт шейп-файла в PostGIS через скрипт Python из QGIS
Я разместил этот вопрос на 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. Количество функций правильное, и таблица пока выглядит неплохо. Так что я не совсем уверен, что на самом деле пошло не так.
Ответы
Для записи. Пример функции 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)
Вы уже были на правильном пути:
Чтобы экспортировать шейп-файл из 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.