备份集过期时间_ArcPy使用之一:SDE数据定时备份

0 前言

原计划国庆节更新一篇,万万没想到居然真的有人催更,感谢小伙伴给了中年后浪熬夜的理由。出于安全和用户体验提升等方面考虑,最近在备份并优化某新城SDE数据。下面记录并总结一下本项任务。

1 现状分析

1.1 数据库现状

  1. 数据类型

    数据种类:基础地理空间框架、调查评价、国土空间规划、管理审批、招商管理、建设管理等类型数据

    存储类型:以要素集(FeatureClass)和数据集(FeatureDataset)类型存储

  2. 数据管理权限

    两个管理员:均具备SDE管理员权限,可读写数据

    两类数据:两个SDE管理员均创建各自的要素集和数据集,且部分数据实时更新

1.2 主要需求

  • 备份SDE中多个管理员用户创建的数据

  • 每天凌晨23:23:23启动备份计划

2 技术路线

2.1 常用方法汇总

备份SDE有诸多技巧,我只说我会的。不想看文字的直接看脑图。

15a5b52efa77d81e731240d88af6f243.png

  • ArcCatalog导出

    优点:上手快

    缺点:数据量大时非最优解

  • SDE命令行:使用sdeexport导出为exp格式文件

    优点:快,命令简单,结果粗暴

    缺点:太快,SDE命令行配置稍复杂,结果过于粗暴所以不直观

  • ArcPy函数批量复制

    优点:较快,代码量小,结果直观

    缺点:与python包融合使用方面可能会遇到未知错误(详见3.1)

  • FME Server中运行scheduled workspace

    优点:绝对可行(但与本文ArcPy主题无关)

    缺点:试用版FME Server已过期,无法测试是否绝对可行(其实schedule是FME Server中常规操作)

2.2 ArcPy路线流程图

见流程图。

04cac579a70d72b7b50891234d64da15.png

3 实现流程

3.1 ArcPy备份SDE

  1. 使用到的ArcPy函数

  • CreateFileGDB_management:创建一个GDB

  • CreateFeatureDataset_management:创建一个DS

  • CopyFeatures_management:复制一个要素集中要素到另一个要素集

  • ListFeatureClasses:

    语法:ListFeatureClasses({wild_card},{feature_type},{feature_dataset})

    说明:设置工作空间后才能使用列表函数

    返回值:返回要素集列表,配置wild_card和feature_type,返回符合条件的要素集列表

  • da.Walk

    语法:Walk (top, {topdown}, {onerror}, {followlinks}, {datatype}, {type})

    说明:遍历目录树,生成目录树中文件名。函数类似于Python的os.walk()函数,但是os.walk()基于文件,不能识别地理数据要素类、表或栅格等数据库内容

    返回值:返回三元组包括工作空间、目录名称和文件名称 (dirpath, dirnames, and filenames)

坑清单

  • 坑1

    坑描述:da.walk()中遍历完FC和DS后,循环不会终止,继续执行导致程序报错

    脱坑:使用break跳出当前循环

  • 坑2

    坑描述:多个SDE管理员可能创建同名FC,导出到同一个GDB中报错

    脱坑:根据用户名分别创建GDB

def SdeBak(gbdpath, gdbname_sde,gdbname_user):    sde_con = 'Database Connections/SDE@Connection to ***.sde'    arcpy.env.overwriteOutput = True    # 设置ws    arcpy.env.workspace = sde_con    str_td = datetime.date.today().strftime('%Y%m%d')    # 指向gdb    out_gdbpath = gbdpath    out_gdbname_sde = '{}{}'.format(gdbname_sde, str_td)    out_gdb_sde = os.path.join(out_gdbpath, out_gdbname_sde + '.gdb')    out_gdbname_user = '{}{}'.format(gdbname_user, str_td)    out_gdb_user = os.path.join(out_gdbpath, out_gdbname_user + '.gdb')    # 创建GDB    arcpy.CreateFileGDB_management(out_gdbpath, out_gdbname_sde, 'CURRENT')    arcpy.CreateFileGDB_management(out_gdbpath, out_gdbname_user, 'CURRENT')    print('SDE GDB Created,GDB Path:{}'.format(out_gdb_sde))    print('CJXCUSER GDB Created,GDB Path:{}'.format(out_gdb_user))    for dirpath, dirnames, filenames in arcpy.da.Walk(sde_con, datatype="FeatureClass",type=['Polygon', 'Polyline', 'Point']):        # 遍历要素集及要素集中要素类并进行拷贝        for ds in dirnames:            # 非SDE用户创建数据不导出            if 'SDE' in ds:                dsname = arcpy.Describe(ds).basename                outdsname = os.path.join(out_gdb_sde, dsname.split('.')[1])                sr = arcpy.Describe(ds).SpatialReference                print(outdsname)                arcpy.CreateFeatureDataset_management(out_gdb_sde, dsname.split('.')[1], sr)                fclist = arcpy.ListFeatureClasses('', '', dsname)                for fc in fclist:                    basename = arcpy.Describe(fc).basename                    outname = os.path.join(outdsname, basename.split('.')[1])                    str = basename.split('.')[1]                    print(str + " Copy Done")                    arcpy.CopyFeatures_management(fc, outname)            elif 'CJXCUSER' in ds:                dsname = arcpy.Describe(ds).basename                outdsname = os.path.join(out_gdb_user, dsname.split('.')[1])                sr = arcpy.Describe(ds).SpatialReference                print(outdsname)                arcpy.CreateFeatureDataset_management(out_gdb_user, dsname.split('.')[1], sr)                fclist = arcpy.ListFeatureClasses('', '', dsname)                for fc in fclist:                    basename = arcpy.Describe(fc).basename                    outname = os.path.join(outdsname, basename.split('.')[1])                    str = basename.split('.')[1]                    print(str + " Copy Done")                    arcpy.CopyFeatures_management(fc, outname)        # 遍历要素类数据并进行拷贝        for fc in filenames:            print(fc)            if 'SDE' in fc:                outname = os.path.join(out_gdb_sde, fc.split('.')[1])            elif 'CJXCUSER' in fc:                outname = os.path.join(out_gdb_user, fc.split('.')[1])            str = fc.split('.')[1]            arcpy.CopyFeatures_management(fc, outname)            print(str + ' Copy Done')        #终止循环        break    print('SDE Backup Accomplished,Backup Date:{}'.format(str_td))

3.2 定时任务调度

  1. schedule包

    上篇B站链接中介绍过schedule包用法,但是对于3号坑的确始料未及。

  • 坑3

    坑描述:通过schedule定时调度arcpy.os.walk()函数时,无返回值

    脱坑:不用此包,换思路

windows自带Task Scheduler

  • 创建一个bat文件,用于执行.py文件

cd C:\Python27\ArcGIS10.2python E:\CJXCSDE_BACKUP\SdeBak.pypause
  • 配置Task Scheduler(任务计划程序)

    说明:不同操作系统界面和步骤略有不同

    位置:管理工具->任务计划程序->创建任务

    触发器配置:设置每天23:23:23执行

    操作配置:新建一个启动程序,指向bat脚本

415f03cafdf0c4f08db075f9ceba760c.png

4 总结

备份SDE看似简单的需求和目标实现起来却是一波三折,感慨下自己知识的非系统性和碎片化,以及思维逻辑的非严密性。道阻且长,行则将至。下篇见。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值