【基于arcpy读取矢量数据写入PostgreSQL】

class DataSdeToPostgerSql():
    # 读取矢量数据,并写入pg库
    def __read_layer(self,in_layer,fields,lyr_name):
        conn = psycopg2.connect(host=self.db['host'], user=self.db['user'], password=self.db['password'],
                                database=self.db['database'], port=self.db['port'])
        cur = conn.cursor()
        datalist = []
        totalCount = int(str(arcpy.GetCount_management(in_layer)))
        spatial_ref = arcpy.Describe(in_layer).spatialReference
        fields_copy = fields
        fid = 0
        with arcpy.da.SearchCursor(in_layer, fields) as cursor:

            for row in cursor:
                sou = []
                for r in row:
                    if r is None:
                        r = 'null'
                    sou.append(r)
                sou[-1] = "GeomFromEWKT('SRID={};{}')".format(spatial_ref.PCSCode, sou[-1])
                sou = tuple(sou)
                datalist.append(sou)
                sou_value = self.__combination_sql(sou)

                fields_copy[-1] = 'SHAPE'
                columns_str = ', '.join(fields_copy)
                ins_sql = "INSERT INTO {} ({}) VALUES({})".format(lyr_name, columns_str, sou_value)
                # print(ins_sql)
                cur.execute(ins_sql)
                fid += 1
                if fid % 500 == 0:
                    conn.commit()
                    msg = '【{}[{}/{}]】'.format(lyr_name, fid, totalCount)
                    logHelp.writelog(self.rid, msg)
                    # break

        # fields_copy[-1] = 'SHAPE'
        # multiples = [i for i in fields_copy if i == 'SHAPE@WKT' is 'SHAPE']
        # placeholders = ', '.join(['%s'] * len(fields_copy))
        # columns_str = ', '.join(fields_copy)
        # # fields_copy = tuple(fields_copy)
        # # cur.copy_from(f, 'tb_user', columns=fields_copy)
        # ins_sql = "INSERT INTO {} ({}) VALUES ({})".format(lyr_name, columns_str,placeholders)
        # cur.executemany(ins_sql, datalist)
        # pyex.execute_values(cur, ins_sql, datalist, page_size=100000)
        conn.commit()
        msg = '【{}[{}/{}]】'.format(lyr_name, fid, totalCount)
        logHelp.writelog(self.rid, msg)
        cur.close()
        conn.close()

    # 组合拼接sql语句
    def __combination_sql(self,sou):
        sou_value = ','

        for variate in sou:
            if 'null' in str(variate):
                sou_value += ',{}'.format(variate)
            elif isinstance(variate, int):
                sou_value += ',{}'.format(variate)
            elif isinstance(variate, unicode):
                sou_value += ",'{}'".format(variate)
            elif 'GeomFromEWKT' in str(variate):
                sou_value += ',{}'.format(variate)
            elif isinstance(variate, str):
                sou_value += ",'{}'".format(variate)
            elif isinstance(variate, float):
                sou_value += ',{}'.format(variate)
            elif isinstance(variate, datetime.datetime):  # type(variate) in ['datetime.datetime']:
                sou_value += ",'{}'".format(variate)
            else:
                sou_value += ',{}'.format(variate)
        sou_value = sou_value.replace(',,', '')
        return sou_value

    def typeof(self,variate):
        type = None
        if isinstance(variate, int):
            type = "int"
        elif isinstance(variate, str):
            type = "str"
        elif isinstance(variate, float):
            type = "float"
        elif isinstance(variate, list):
            type = "list"
        elif isinstance(variate, tuple):
            type = "tuple"
        elif isinstance(variate, dict):
            type = "dict"
        elif isinstance(variate, set):
            type = "set"
        return type
    # 判断pg库有无该图层,有则删除创建,无则创建
    def __creat_layer(self,layer_name):
        if self.__del_layer(layer_name):
            try:
                msg = '获取图层数据结构'
                logHelp.writelog(self.rid, msg)
                additional_sql = '('
                for oField in self.all_fields:
                    fid = oField['Type'].lower()
                    if oField['Type'].lower() in ['string']:
                        if oField['length'] == 0 or oField['length'] >240:
                            additional_sql += '{} text,'.format(oField['Field'])
                        else:
                            additional_sql += '{} varchar({}),'.format(oField['Field'], oField['length'])
                    elif oField['Type'].lower() in ['smallinteger']:
                        additional_sql += '{} integer,'.format(oField['Field'])
                    elif oField['Type'].lower() in ['double']:
                        additional_sql += '{} numeric,'.format(oField['Field'])
                    elif oField['Type'].lower() in ['datetime','date']:
                        additional_sql += '{} date,'.format(oField['Field'])
                    elif oField['Type'].lower() in ['geometry']:
                        additional_sql += 'SHAPE geometry,'
                    else:
                        additional_sql += '{} {},'.format(oField['Field'], oField['Type'])
                additional_sql += ',);'

                msg = '数据结构获取成功'
                print(msg)
                logHelp.writelog(self.rid, msg)

                additional_sql = additional_sql.replace(',,','')
                msg = 'PostgreSql数据库创建表【{}】开始'.format(layer_name)
                print(msg)
                logHelp.writelog(self.rid, msg)
                ct_sql = 'CREATE TABLE {} {}'.format(layer_name, additional_sql)
                logHelp.writelog(self.rid, ct_sql)
                print(ct_sql)
                conn = psycopg2.connect(host=self.db['host'], user=self.db['user'], password=self.db['password'],
                                        database=self.db['database'], port=self.db['port'])
                cur = conn.cursor()
                cur.execute(ct_sql)
                conn.commit()
                cur.close()
                conn.close()
                msg = 'PostgreSql数据库创建表【{}】成功'.format(layer_name)
                print(msg)
                logHelp.writelog(self.rid, msg)
                m_falg = True

            except Exception as err:
                m_falg = False
                msg = 'PostgreSql数据库创建表【{}】失败'.format(layer_name)
                print(msg)
                logHelp.writelog(self.rid, msg)
                logHelp.writelog(self.rid, str(err))
                print(str(err))

        else:
            m_falg = False
        return m_falg

    # 浮点型,Float
    # 长整型,Long
    # 日期型,Date
    # 文本型,Text
    # 短整型,Short
    # 双精度,Double
    def esriFieldType(self, field_type):
        type_value = ''
        '''
        esriFieldTypeSmallInteger = 0,
        esriFieldTypeInteger = 1,
        esriFieldTypeSingle = 2,
        esriFieldTypeDouble = 3,
        esriFieldTypeString = 4,
        esriFieldTypeDate = 5,
        esriFieldTypeOID = 6,
        esriFieldTypeGeometry = 7,
        esriFieldTypeBlob = 8,
        esriFieldTypeRaster = 9,
        esriFieldTypeGUID = 10,
        esriFieldTypeGlobalID = 11,
        esriFieldTypeXML = 12
        '''
        if field_type == 0:
            type_value = 'Short'
        elif field_type == 1:
            type_value = 'Long'
        elif field_type == 2:
            type_value = 'Float'
        elif field_type == 3:
            type_value = 'Double'
        elif field_type == 4:
            type_value = 'Text'
        elif field_type == 5:
            type_value = 'Date'
        elif field_type == 6:
            type_value = 'OID'
        elif field_type == 7:
            type_value = 'Geometry'
        elif field_type == 8:
            type_value = 'Blob'
        elif field_type == 9:
            type_value = 'Raster'
        elif field_type == 10:
            type_value = 'GUID'
        elif field_type == 11:
            type_value = 'GlobalID'
        elif field_type == 12:
            type_value = 'XML'

        return type_value

    # 删除图层,
    def __del_layer(self,layer_name):
        try:
            select_sql = "select count(*) from pg_class where relname = '{}';".format(layer_name.lower())

            conn = psycopg2.connect(host=self.db['host'],
                                    user=self.db['user'],
                                    password=self.db['password'],
                                    database=self.db['database'],
                                    port=self.db['port'])
            cur = conn.cursor()
            cur.execute(select_sql)
            rows = cur.fetchall()
            m_count = rows[0][0]
            if int(m_count) == 1:
                drop_sql = 'DROP TABLE {};'.format(layer_name)
                cur.execute(drop_sql)
                conn.commit()
            cur.close()
            conn.close()
            m_falg = True
        except Exception as err:
            m_falg = False
            print(str(err))

        return m_falg

    # 获取字段,输入图层
    def __GetFields(self, in_features):
        flds_out = []
        out_fields = []
        flds = arcpy.ListFields(in_features)
        for fld in flds:
            if not fld.type in ['OID'] and not fld.name.upper() in ['SHAPE.AREA', 'SHAPE.LEN', 'SHAPE_AREA',
                                                            'SHAPE_LENGTH','SHAPE']:
                m_field = {
                    'Field': fld.name.upper(),
                    'Alias': fld.aliasName,
                    'Type': fld.type,
                    'Editable': fld.editable,
                    'Required': fld.required,
                    'length': fld.length,
                    'Scale': fld.scale,
                    'Precision': fld.precision
                }
                flds_out.append(m_field)
        # for field in flds_out:
        #     if field['Field'] == 'SHAPE':
        #         field['Field'] = field['Field']+ "@WKT"
        #     out_fields.append(field)

        m_field = {
            'Field': 'SHAPE@WKT'.upper(),
            'Alias': '',
            'Type': 'Geometry',
            'Editable': '',
            'Required': '',
            'length': 0,
            'Scale': 0,
            'Precision': 0
        }
        flds_out.append(m_field)
        return flds_out

    # 对外开放调用,传入图层,pg连接参数 'postgis',#
    def main(self, in_table, db, rid,out_table):
        self.db = {
            'host': db['ip'],
            'user': db['user'],
            'password': db['pwd'],
            'database': db['sid'],
            'port': int(db['port'])
        }
        # in_table = 'D:/Data/Workspace/DLTB_441324.gdb/G2019XZDCQHAORP9GQK'
        self.rid = rid
        lyr_name = out_table.split('/')[-1]
        self.all_fields = self.__GetFields(in_table)
        if self.__creat_layer(lyr_name):
            Search_fields = []
            for i in self.all_fields:
                Search_fields.append(i['Field'])
            msg = '解析矢量数据,写入pg数据库。'
            logHelp.writelog(self.rid, msg)
            tim_start = datetime.datetime.now()
            self.__read_layer(in_table,Search_fields,lyr_name)
            tim_end = datetime.datetime.now()
            tim_dif = tim_end - tim_start
            msg = '写入pg数据库完成,耗时:{}'.format(tim_dif)
            logHelp.writelog(self.rid, msg)

        print (1)


if __name__ == '__main__':
    db = {
        'ip': '192.xxx.xxx.xx',
        'user': 'xxx',
        'pwd': 'xxx',
        'sid': 'xxx',
        'port': '5432'
    }
    DataSdeToPostgerSql().main('d:/data/127.0.0.1.sde/input_layer',db, '123', 'new_table')

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值