Eksportowanie Shapefile do PostGIS za pomocą skryptu Python z QGIS

Sep 28 2020

Opublikowałem to pytanie na StackOverFlow, gdzie zalecono, aby zamieścić je tutaj.

Chcę wyeksportować plik shapefile do PostGIS za pomocą skryptu Python z QGIS. Używam QGIS 3.10, PostgreSQL 10 i PostGIS 2.5 w systemie Windows 10. Próbowałem użyć qgis:importintopostgis:

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

Powoduje to wyświetlenie komunikatu o błędzie:

„.... Wystąpiły błędy podczas wykonywania algorytmu”.

Co ciekawe, współpracuje z DB Managerem, który wydaje się być GUI qgis:importintopostgis.

Różnice, które widzę, to źródłowe i docelowe identyfikatory SRID. Nie wiem, jak wprowadzić te parametry w qgis: importintopostgis. Nie jestem też pewien, czy nie musiałbym wpisywać nazwy użytkownika i hasła do bazy danych, ale znowu nie widzę, gdzie wprowadzić te parametry qgis:importintopostgis.

Próbowałem także `gdal: importvectorintopostgisdatabaseavailableconnections:

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

Działa bez komunikatu o błędzie, ale również nie importuje tabeli do PostGIS. Co ja robię źle? Czy istnieje metoda, która działa z Pythonem z QGIS?

Cześć @Jakob. To działa. Dziękuję Ci.

Cześć @DirkB: Biegam:

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)

Otrzymuję następujący komunikat o błędzie:

Traceback (ostatnie wywołanie ostatnio): Plik "C: \ PROGRA ~ 2 \ QGIS3 ~ 1.10 \ apps \ Python37 \ lib \ code.py", wiersz 90, w runcode exec (code, self.locals) File "", wiersz 1, w pliku „”, wiersz 98, w pliku „C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ tools \ general.py”, wiersz 106, w biegu return Processing.runAlgorithm (algOrName, parameters, onFinish, feedback, context) Plik "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ core \ Processing.py", wiersz 181, w runAlgorithm podnieść QgsProcessingException (msg) _core.QgsProcessingException: Wystąpiły błędy podczas wykonywania algorytmu.

Tworzy tabelę w mojej bazie danych PostGIS. Ale tabela jest pusta i zawiera tylko pola „nummer” i „geom”. Czy muszę gdzieś definiować pola w parametrach? Czy muszę dołączyć do tabeli, która ma już pola?

Znalazłem Historię, dobrze wiedzieć. Ale nie rejestruje, kiedy uruchamiam DB Manager. I nie znalazłem żadnej innej wtyczki do importowania warstwy wektorowej do PostGIS. Który z nich miałeś na myśli?

Znalazłem tę funkcję w przyborniku Przetwarzanie. Uruchomiłem go pomyślnie i wykorzystałem tekst z historii w Pythonie. Po chwili pojawił się komunikat o błędzie „... Wystąpiły błędy podczas wykonywania algorytmu.” Ale wyeksportował tabelę do PostgreSQL. Liczba funkcji jest poprawna, a tabela na razie wygląda dobrze. Więc nie jestem całkiem pewien, co właściwie poszło nie tak.

Odpowiedzi

4 Jakob Sep 29 2020 at 14:42

Dla porządku. Przykład funkcji Pythona używającej OGR2OGR poza QGIS w OSGEO QGIS dist. Użyłem podczas spaceru po dysku, znajdując pliki kształtów 900 w katalogach rekurencyjnych i przesyłane do PostGIS bez błędów. Aby uprościć kod, usunąłem niektóre nazewnictwo tabel GUID, aby uniknąć zduplikowanych nazw tabel.

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

Byłeś już na dobrej drodze:

Aby wyeksportować Shapefile z QGIS 3 do PostGIS poprzez pyqgis, możesz użyć następującego kodu:

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)

Ponieważ istnieje również wtyczka do importowania warstwy wektorowej do PostGIS, możesz ją wykonać, a następnie zobaczyć kod z History Protocol.

Wtyczka to wtyczka GDAL z Processing Toolbox "Eksport do PostgreSQL (dostępne połączenia)"

Wtyczka wygląda następująco i pewnie łatwiej byłoby jej najpierw użyć i po sprawdzeniu Historii wykonanych procesów zaimplementować swój kod.

Tutaj jest link do dokumentacji z QGIS 2 QGIS 2.6 docs

Tutaj jest link do dokumentacji QGIS 3 QGIS 3.10 docs

Twój kod z:

 'GTYPE': 0

oznacza brak typu geometrii przy okazji. 5 byłoby wielokątem.

Więcej informacji znajduje się w linkach do dokumentacji QGIS 2 lub QGIS 3 o parametrach.