Xuất shapefile sang PostGIS thông qua tập lệnh Python từ QGIS

Sep 28 2020

Tôi đã đăng câu hỏi này trên StackOverFlow, nơi tôi khuyên bạn nên đăng nó thay vì ở đây.

Tôi muốn xuất một tệp hình dạng vào PostGIS thông qua một tập lệnh Python từ QGIS. Tôi đang sử dụng QGIS 3.10, PostgreSQL 10 và PostGIS 2.5 trên Windows 10. Tôi đã thử sử dụng qgis:importintopostgis:

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

Điều đó tạo ra một thông báo lỗi:

“.... Đã xảy ra lỗi khi thực hiện thuật toán.”

Điều thú vị là nó hoạt động với Trình quản lý DB, có vẻ như là một GUI của qgis:importintopostgis.

Sự khác biệt mà tôi có thể thấy là SRID nguồn và mục tiêu. Tôi không biết cách nhập các thông số này vào qgis: importintopostgis. Tôi cũng không chắc liệu mình có cần nhập tên người dùng và mật khẩu cho cơ sở dữ liệu hay không, nhưng một lần nữa tôi không thấy phải nhập các thông số này vào đâu qgis:importintopostgis.

Tôi cũng đã thử `gdal: importvectorintopostgisdatabaseavailableconnections:

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

Điều đó chạy mà không có thông báo lỗi nhưng cũng không nhập bảng vào PostGIS. Tôi đang làm gì sai? Có phương pháp nào hoạt động với Python từ QGIS không?

Xin chào @Jakob. Điều đó hoạt động. Cảm ơn bạn.

Xin chào @DirkB: Tôi chạy:

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)

Sau đó, tôi nhận được thông báo lỗi sau:

Traceback (lần gọi gần đây nhất): Tệp "C: \ PROGRA ~ 2 \ QGIS3 ~ 1.10 \ apps \ Python37 \ lib \ code.py", dòng 90, trong tệp runcode thực thi (mã, self.locals) "", dòng 1, trong Tệp "", dòng 98, trong Tệp "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr /./ python / plugins \ processing \ tools \ general.py", dòng 106, đang chạy trả về Xử lý.runAlgorithm (algOrName, tham số, onFinish, phản hồi, ngữ cảnh) Tệp "C: /PROGRA~2/QGIS3~1.10/apps/qgis-ltr/./ python / plugins \ processing \ core \ Processing.py", dòng 181, trong runAlgorithm nâng QgsProcessingException (msg) _core.QgsProcessingException: Đã xảy ra lỗi khi thực thi thuật toán.

Nó tạo một bảng trong cơ sở dữ liệu PostGIS của tôi. Nhưng bảng trống và chỉ có các trường ‚nummer 'và‚ geom'. Tôi có phải xác định các trường ở đâu đó trong các tham số không? Hay tôi phải thêm vào một bảng đã có các trường?

Tôi đã tìm thấy Lịch sử, điều đó thật tốt khi biết. Nhưng nó không ghi khi tôi chạy DB Manager. Và tôi không tìm thấy bất kỳ plugin nào khác để nhập lớp vectơ vào PostGIS. Bạn đã tham khảo cái nào?

Tôi đã tìm thấy chức năng này trong hộp công cụ Xử lý. Tôi đã chạy nó thành công và sử dụng văn bản từ lịch sử bằng Python. Điều đó sau một thời gian tạo ra một thông báo lỗi "... Đã xảy ra lỗi khi thực thi thuật toán." Nhưng nó đã xuất bảng sang PostgreSQL. Số lượng các tính năng là chính xác và bảng có vẻ ổn cho đến nay. Vì vậy, tôi không chắc chắn điều gì đã xảy ra.

Trả lời

4 Jakob Sep 29 2020 at 14:42

Đối với hồ sơ. Ví dụ về một hàm Python sử dụng OGR2OGR bên ngoài QGIS của một phiên bản OSGEO QGIS. Tôi đã sử dụng trong một lần đi bộ tìm 900 tệp hình dạng trong thư mục đệ quy và tải lên PostGIS mà không có lỗi. Để đơn giản hóa mã, tôi đã loại bỏ một số cách đặt tên bảng GUID để tránh trùng lặp tên bảng.

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

Bạn đã đi đúng đường:

Để xuất một Shapefile từ QGIS 3 sang PostGIS thông qua pyqgis, bạn có thể sử dụng mã sau:

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)

Vì cũng có một Plugin để nhập lớp vectơ vào PostGIS, bạn có thể thực thi điều đó và sau đó xem mã từ Giao thức lịch sử.

Plugin này là plugin GDAL từ Hộp công cụ xử lý "Xuất sang PostgreSQL (các kết nối có sẵn)"

Plugin trông giống như sau và có lẽ sẽ dễ dàng hơn khi sử dụng nó trước tiên và sau khi kiểm tra Lịch sử của các quy trình đã thực thi, hãy triển khai mã của bạn.

Đây là liên kết đến tài liệu từ tài liệu QGIS 2 QGIS 2.6

Đây là liên kết đến tài liệu cho tài liệu QGIS 3 QGIS 3.10

Mã của bạn với:

 'GTYPE': 0

có nghĩa là không có kiểu hình học btw. 5 sẽ là đa giác.

Thông tin thêm có trong các liên kết đến tài liệu QGIS 2 hoặc QGIS 3 về các thông số.