# coding=utf-8 import fnmatch import os import sys import arcpy from imp import reload from functions import * from sys_config import SysConfig from logger import Logger reload(sys) sys.setdefaultencoding('utf8') # EPS SDE 系统表列表 g_sys_tb = ['SS_BDCDYHINFO', 'SS_GISDBLINKINFO', 'SS_LOGINFO', 'SS_ROLEINFO', 'SS_ROLEMXDINFO', 'SS_TABSAPCEPERMISSIONINFO', 'SS_USERINFO', 'SUNWAY_INIINFO', 'SS_LAYERINFO', 'GE_ENTITYCODE', 'GE_ENTITYIDTB'] class SdeSynchronous: def __init__(self, conf, log): self.config = conf self.logger = log self.error_count = 0 self.src_sde = None self.txt_ct_file = None # 记录数量的txt文件 self.out_gdb_path = None self.out_gdb_files = {} self.only_changed_layers = False def run(self): """同步的主函数""" # 1.连接SDE数据库 self.src_sde = self.get_connection(str(u"源库SDE连接")) if self.src_sde == "" or self.src_sde is None: self.logger.error("src_sde Connection file not exist!") else: self.create_gdb_files() txt_path = self.out_gdb_path + "\\" + str(u"图层数量统计.txt").encode("utf-8") self.txt_ct_file = open(txt_path, "wb+", buffering=0) # 开始编辑SDE edit = self.start_edit() # 获取上次同步的时间 last_sync_datetime = self.get_last_sync_datetime() if last_sync_datetime == "": self.config.last_sync_datetime = self.config.curr_sync_datetime else: self.config.last_sync_datetime = last_sync_datetime self.logger.log('===' + self.config.last_sync_datetime + "==TO==" + self.config.curr_sync_datetime + "===") # 获取fc列表 fc_list = arcpy.ListFeatureClasses("*", "all") # 获取同步工程信息 last_gongch, last_yewbh = self.get_projects_info() self.write_start_event_logs(last_gongch) # 输出增量 self.sde2gdb_feature_list(fc_list) # 获取数据集列表 ds_list = arcpy.ListDatasets("*", "Feature") # 逐个数据集输出 for DS in ds_list: str_msg = "Process Dataset: " + DS.encode("gb2312") print(str_msg) index = DS.rfind('.') ds_name = DS[index + 1:] desc = arcpy.Describe(DS) sr = desc.spatialReference # 更改工作空间回到SDE arcpy.env.workspace = self.src_sde # 获取数据集中fc列表 fc_list = arcpy.ListFeatureClasses(feature_dataset=DS) # 输出增量 self.sde2gdb_feature_list(fc_list) # 获取关联关系表列表 re_table_list = arcpy.ListTables("SHDLG500.*", "all") self.sde2gdb_table_list(re_table_list) bool_save = True if self.error_count == 0 else False if bool_save: # 记录同步成功时间 self.set_last_sync_datetime() # 停止编辑 self.stop_edit(edit, bool_save) # 执行回调返回gdb增量输出结果 self.return_result("gdb", bool_save, last_gongch, last_yewbh) # 结果输出到日志信息 str_message = u"输出增量GDB完成" if bool_save else u"输出增量GDB失败" self.logger.log(str_message.encode("gb2312")) arcpy.env.workspace = self.out_gdb_path + "\\" + self.out_gdb_files["Delete"] delete_fcs = arcpy.ListFeatureClasses() for FC in delete_fcs: arcpy.AddField_management(FC, "FEATUREGUIDCOPY", "TEXT") arcpy.CalculateField_management(FC, "FEATUREGUIDCOPY", "[FEATUREGUID]", "VB") arcpy.DeleteIdentical_management(FC, ["FEATUREGUIDCOPY"]) arcpy.DeleteField_management(FC, ["FEATUREGUIDCOPY"]) if bool_save: # 开始输出mdo # self.copy_to_mdo(str(self.out_gdb_path).encode('gbk')) # 转换到旧标准的gdb self.trans_to_old() # 输出保密的gdb self.output_security_gdb() # TODO 写旧标准输出完成的标记文档 # WriteFinishFlag # 执行回调返回mdo输出结果 self.return_result("mdo", bool_save, last_gongch, last_yewbh) # 结果输出到日志信息 str_message = u"输出增量MDO完成" if bool_save else u"输出增量MDO失败" self.logger.log(str_message.encode("gb2312")) def create_gdb_files(self): try: # 创建输出GDB tt = self.config.curr_sync_datetime self.out_gdb_path = self.config.pathname + "\\" + u"NEWGDB\\" + tt[:tt.find(' ')] create_dir(self.out_gdb_path) self.out_gdb_files = {"Add": "addFeatures.gdb", "Edit": "editFeatures.gdb", "Delete": "deleteFeatures.gdb"} for key in self.out_gdb_files.keys(): gdb_path = self.out_gdb_path + "\\" + self.out_gdb_files[key] if arcpy.Exists(gdb_path): arcpy.Delete_management(gdb_path) arcpy.CreateFileGDB_management(self.out_gdb_path, self.out_gdb_files[key]) except Exception as e: self.logger.error("create_gdb error:\n" + str(e)) def get_connection(self, sub_path): """获取SDE连接""" for fileName in os.listdir(self.config.pathname + "\\" + sub_path.encode("gb2312")): if fnmatch.fnmatch(fileName, '*.sde'): return self.config.pathname + "\\" + sub_path + "\\" + fileName return "" def start_edit(self): """开始编辑""" arcpy.env.workspace = self.src_sde print(str(self.src_sde).encode('gb2312')) edit = arcpy.da.Editor(self.src_sde) edit.startEditing(False, False) edit.startOperation() return edit def stop_edit(self, edit, bool_save): """停止编辑""" arcpy.env.workspace = self.src_sde # 停止编辑 edit.stopOperation() edit.stopEditing(bool_save) def write_start_event_logs(self, last_gongch): """反查更新的项目编号,并写OA事件""" for GongCH in last_gongch: write_event_log("OutPutMap_GDB", GongCH, u"开始".encode('utf8'), self.config.logfile_name.decode('gbk').encode('utf8'), u"增量输出GDB文件开始".encode('utf8')) # write_event_log("OutPutMap_MDO", # GongCH, # u"开始".encode('utf8'), # self.config.logfile_name.decode('gbk').encode('utf8'), # u"增量输出MDO文件开始".encode('utf8')) def get_projects_info(self): feature_class = self.config.sde_scheme() + "." + self.config.updateregion() time_values = {"from_time": self.config.last_sync_datetime, "to_time": self.config.curr_sync_datetime} time_condition = """UPDATETIME>=TO_DATE('{from_time}','YYYY-MM-DD HH24:MI:SS') and DOWNLOADTIME=TO_DATE('{last_time}','YYYY-MM-DD HH24:MI:SS') " \ "and {del_time_field}{}".format(section_name, fc_name, last_value, value)) def set_last_max_object_id(self, fc_name, objectid): """记录最大ObjectID""" self.set_iniinfo_value_int("SHDB_LayerInfo_LastMaxID", fc_name, objectid) # 记录同步完成状态 self.set_iniinfo_value_int("SHDB_LayerInfo_SynchronousStatus", fc_name, 1) def set_last_sync_datetime(self): """记录同步时间""" section_name = self.config.sde_scheme() + "_Dbsyn_gdb" key_name = "LastExportTime" self.set_iniinfo_value_int(section_name, key_name, self.config.curr_sync_datetime) def get_max_object_id(self, fc_name): """获取图层当前最大ObjectID""" try: with arcpy.da.SearchCursor(fc_name, "OBJECTID", where_clause="ObjectID>0", sql_clause=(None, 'ORDER BY OBJECTID DESC')) as cur: try: return next(cur)[0] except StopIteration: return 0 except arcpy.ExecuteError as e: errmsg = str(arcpy.GetMessages(2).encode("gb2312")) print("Error occurred when accessing {}: {}".format(fc_name, errmsg)) self.logger.log("Error occurred when accessing {}: {}".format(fc_name, e)) return 0 def get_sys_time_condition(self, is_history): """当前增量同步时间""" time_field = self.config.updatetime_field_history() if is_history else self.config.updatetime_field() str_sql = "{}>=TO_DATE('{}','YYYY-MM-DD HH24:MI:SS') and {}