Skip to main content

Операции по автоматическому согласованию и закреплению данных сервис-ориентированных версий с поддержкой синхронизации.

Администраторы версий могут использовать скрипты Python для автоматизации планового согласования версий реплик после того, как мобильные сотрудники согласуют изменения в данные, включенные в сервис-ориентированные версии.

Этот рабочий процесс применяется для управления версиями реплик, созданных с помощью векторного веб-слоя (сервиса объектов) с поддержкой синхронизации, с данными сервис-ориентированных версий.

Дополнительные сведения об автономных картах с данными сервис-ориентированных версий

Примечание:

Этот рабочий процесс специфичен для управления версиями ветвей. Традиционное управление версиями требует других административных задач. Если вы используете традиционное управление версиями, вы также можете автоматизировать операции согласования и публикации с помощью Python.

Применимый сценарий

Пример Python в следующем разделе использует сервис объектов ArcGIS REST API и функции ArcPy для согласования и публикации версий реплик с установленными правилами атрибутов проверки. Ниже описывается, когда вы будете использовать этот образец кода, и что делает скрипт.

Примечание:

Этот скрипт - пример рабочего процесса с установкой конкретных данных. Ваши рабочие процессы не обязательно должны в точности соответствовать модели данных, но основные концепции и логику скрипта все равно можно использовать для автоматизации процессов для вашей организации. Например, вы можете не использовать правила проверки, и, соответственно изменить скрипт и удалить из него проверку с помощью правил. Также, в ряде случаев при использовании правил проверки вы можете захотеть согласовать, запустить проверку и закрепить изменения в каждой версии отдельно, перед запуском операции проверки, чтобы быть уверенным, что изменения, сделанные другими пользователями, будут включены в проверку.

Предварительное условие:

В этом примере настройка данных следующая:

  • Векторный веб-слой должен иметь включенную функцию синхронизации, содержать данные сервис-ориентированной версии, а также должен быть опубликован с включенным функционалом управления версиями, и с выбранной опцией Создать версию для каждой скачанной карты, это требует ArcGIS Enterprise не ниже версии 10.8.1.

  • Реплики были созданы, когда карта, содержащая векторный веб-слой, находилась в автономном режиме

  • У пользователя портала должны быть учетные данные участника либо с ролью администратора портала по умолчанию, либо с пользовательской ролью, которой предоставлены права доступа для управления версиями.

  • В этом примере к данным также применены правила атрибутов проверки и включена функция сервера проверки. Это - не обязательное требование для работы с версиями реплик, но позволяет обеспечить целостность данных.

Ниже описаны шаги, которые необходимо пройти после того, как будут выполнены все необходимые условия:

  1. Список версий реплик для этого сервиса объектов (векторного веб-слоя) можно получить с помощью ресурса replicas в ArcGIS REST API.

  2. Используйте ресурс versionsInfos в ArcGIS REST API для получения свойств версии.

    Используя эти свойства, создайте фильтр, чтобы получить только те версии, в которых дата оценки равна нулю или измененная дата больше последней даты оценки (то есть с момента последней оценки были сделаны изменения). Добавьте имена версий, удовлетворяющие фильтру, в список listOfVersionsToValidate, который будет оцениваться.

  3. Для каждой версии в списке оценки используйте операцию evaluate в ArcGIS REST API, чтобы выполнить оценку правил атрибутов проверки в этом сервисе.

    Если оценка прошла успешно без возвращенных ошибок, то версия реплики готова к согласованию и публикации. Если оценка прошла успешно, но ошибки возвращаются, не публикуйте изменения и создайте сообщение, чтобы ошибки можно было проверить и исправить вручную.

  4. Для версий реплик, которые были успешно оценены без ошибок, запустите инструмент Согласовать версии с возможностью публикации изменений.

  5. Запустите инструмент Согласовать версии с возможностью только согласования (без публикации) на всех версиях реплик.

Образец кода

Приведенный ниже образец кода Python завершает перечисленные выше операции. Этот скрипт включает в себя возможность создания файла журнала, который захватывает выходные данные каждой завершенной операции, и который можно просмотреть после завершения этого скрипта.

# Import modules
import arcpy, traceback, urllib, json, urllib.request, urllib.parse, os, urllib.error, datetime
# Overwrite the reconcile log output each time the script is run
arcpy.env.overwriteOutput = True
# Script parameters
serviceName = "MyServiceName"
baseURL = "https://MyServer.MyDomain.com"
portalAdmin = "MyAdminUser"
portalAdminPwd = "MyAdmin.Password"
logFileScript = "C:/Logs/validateRecPostScriptLog.txt"
logfileOutputRecPost = 'C:/Logs/reconcile_log.txt'
# Choose to output a log file for the script
outputScriptReport = True
# Define functions
def openURL(url, params=None):
 """This function used to open a URL and returns the json response"""
 try:
     request_params = {'f':'pjson'}
     if params:
         request_params.update(params)
     encodedParams = urllib.parse.urlencode(request_params)
     request = urllib.request.urlopen(url, encodedParams.encode('UTF-8'))
     response = request.read()
     json_response = json.loads(response)
     return json_response
 except:
     print (traceback.format_exc())
def versionInfo(versionOwner=""):
 """This function queries the versions owned by the versionOwner.
 It returns a list of dictionaries."""
 vmsUrlinfo = "{}/server/rest/services/{}/VersionManagementServer/versionInfos?&ownerFilter={}&includeHidden=&f=json&token={}".format(baseURL, serviceName, versionOwner, token)
 response = openURL(vmsUrlinfo)
 if response['success'] == True:
     versionsDict = response['versions']
     return versionsDict
 else:
     return("Unable to get version info")
def evaluateUrl(validationUrl, validate_params):
 """This function runs evaluate on the validation server
 It returns the json response."""
 evalJsonResp = openURL(validationUrl, validate_params)
 if evalJsonResp['success'] == False:
     return [False, evalJsonResp]
 else:
     return [True, evalJsonResp]
def generateMessage(msg, print_statement=True):
 """This function generates messages as the script runs. If print_statement
 is set to True, print to the screen. If outputScriptReport is set to true,
 write the message to the logfile"""
 if outputScriptReport == True:
     with open(logFileScript, 'a') as log_file:
         log_file.write(msg + "\n")
 if print_statement == True:
     print(msg)
def recPostVersions(versionList, post):
 """This function runs the Reconcile Versions GP tool to reconcile
 and optionally post to the feature service"""
 if post == True:
     postVersion = "POST"
 elif post == False:
     postVersion = "NO_POST"
 # Reconcile and post the replica versions
 # This tool is set to abort if there are conflicts and detects conflicts by object
 arcpy.management.ReconcileVersions(featureService,
                                     'ALL_VERSIONS',
                                     'sde.DEFAULT',
                                      versionList,
                                     'NO_LOCK_ACQUIRED',
                                     'ABORT_CONFLICTS',
                                     'BY_OBJECT',
                                     'FAVOR_EDIT_VERSION',
                                     postVersion,
                                     'KEEP_VERSION',
                                     logfileOutputRecPost)
 generateMessage(arcpy.GetMessages()+"\n")
# Start execution
generateMessage('Starting Validation/Reconcile/Post Automation Script... {:%Y-%b-%d %H:%M:%S}\n'.format(datetime.datetime.now()))
# Sign in to ArcGIS Enterprise
signIntoPortal = arcpy.SignInToPortal(baseURL+"/portal", portalAdmin, portalAdminPwd)
generateMessage("Signed into ArcGIS Enterprise {} as user {}".format(baseURL+"/portal", portalAdmin))
# Get the token returned by the SignIntoPortal arcpy function to use for making REST requests
token = signIntoPortal['token']
# Build the feature service URL
featureService = "{}/server/rest/services/{}/FeatureServer".format(baseURL, serviceName)
# Get a list of the replica versions from the REST endpoint
listOfRepVersions = []
replicaVersionsURL = featureService + "/replicas?returnVersion=true&f=pjson"
repVersionsJson = openURL(replicaVersionsURL, signIntoPortal)
for repVersion in repVersionsJson:
 versionName = repVersion['replicaVersion']
 listOfRepVersions.append(versionName)
# Create an empty list to append version names to validate
listOfVersionsToValidate = []
# Iterate through each version returned by the versionInfo() function to find
# the versions that need to be validated that are also in the listOfRepVersions list
for version in versionInfo():
 print("")
 # Parse the version info response, which is a python dictionary/json
 # If the version name is sde.DEFAULT, pass since we do not want to evaluate the default version
 if version['versionName'] == "sde.DEFAULT":
     pass
 # If the modifiedDate property is null, pass
 elif version['modifiedDate'] == "None":
     pass
 # If the evaluation date is null, append the version name to the list to listOfVersions to be evaluated
 elif version['evaluationDate'] == None:
     if version['versionName'] in listOfRepVersions:
         listOfVersionsToValidate.append(version['versionName'])
 # If the evaluation date is not null, but it has been modifed since the last evaluation, add it to the list to be validated
 elif version['evaluationDate'] != None and version['modifiedDate'] > version['evaluationDate']:
     if version['versionName'] in listOfRepVersions:
         listOfVersionsToValidate.append(version['versionName'])
 # If none of these conditions are met
 else:
     generateMessage("Version {} will not be validated.".format(version['versionName']))
# Validate versions
generateMessage('The following versions will be validated: {}\n'.format(listOfVersionsToValidate))
# Create lists to contain versions where the validation passed or failed
failEval = []
passEval = []
# For each version in the list of versions, build the json request needed to validate
for i in listOfVersionsToValidate:
 validate_params = { "gdbVersion": i,
          "sessionId": "",
          "evaluationArea": "",
          "changesInVersion": "true",
          "selection": "",
          "evaluationType": '["validationRules"]',
          "returnEdits": "true",
          "async": "false",
          "f": "pjson",
          "token": token
 }
 # Build the REST URL used to validate the service
 validationUrl = baseURL + "/server/rest/services/"+ serviceName +"/ValidationServer/evaluate"
 # Call the evalVersion() function to validate the version
 evalVersion = evaluateUrl(validationUrl, validate_params)
 # If the evaluate failed, append to the failEval list
 if evalVersion[0] == False:
     generateMessage("Evalution of version {} failed".format(i))
     generateMessage(str(evalVersion[1]))
     failEval.append(i)
 # If the evaluate passed, check to see if errors were returned
 elif evalVersion[0] == True:
     # If errors are returned, only reconcile this version
     if evalVersion[1]['errorsIdentified'] != 0:
         generateMessage("{} Errors were identified in version {}.\nThe version will be reconciled but will not be posted.\n".format((str(evalVersion[1]['errorsIdentified'])),i))
         generateMessage(str(evalVersion[1]), False)
     # If errors were not found this version can be posted
     else:
         generateMessage("Evaluation of version {} passed with no errors identified.\nThis version will be reconciled and posted.\n".format(i))
         generateMessage(str(evalVersion[1]))
         passEval.append(i)
# The versions that passed validation should be reconciled/posted
generateMessage('\nThe following versions passed validation and will be reconciled and posted: {}\n'.format(passEval))
# Run recPostVersions on the list of versions that passed evaluation with the option to post
recPostVersions(passEval, True)
# Open the reconcile log file and append the results to our report
with open(logfileOutputRecPost, 'r') as openRecLog:
 generateMessage(openRecLog.read(), False)
# Run recPostVersions with the option to reconcile all replica versions, no post
recPostVersions(listOfRepVersions, False)
# Open the reconcile log file and append the results to our report
with open(logfileOutputRecPost, 'r') as openRecLog:
 generateMessage(openRecLog.read(), False)
# Script execution complete
generateMessage('Validate, Reconcile, & Post Script Complete.')