Доступно с лицензией Standard или Advanced.
Администраторы версий могут использовать скрипты Python для автоматизации планового согласования версий реплик после того, как мобильные сотрудники согласуют изменения в данные, включенные в сервис-ориентированные версии.
Этот рабочий процесс применяется для управления версиями реплик, созданных с помощью векторного веб-слоя (сервиса объектов) с поддержкой синхронизации, с данными сервис-ориентированных версий.
Дополнительные сведения об автономных картах с данными сервис-ориентированных версий
Примечание:
Этот рабочий процесс специфичен для управления версиями ветвей. Традиционное управление версиями требует других административных задач. Если вы используете традиционное управление версиями, вы также можете автоматизировать операции согласования и публикации с помощью Python.
Применимый сценарий
Пример Python в следующем разделе использует сервис объектов ArcGIS REST API и функции ArcPy для согласования и публикации версий реплик с установленными правилами атрибутов проверки. Ниже описывается, когда вы будете использовать этот образец кода, и что делает скрипт.
Примечание:
Этот скрипт - пример рабочего процесса с установкой конкретных данных. Ваши рабочие процессы не обязательно должны в точности соответствовать модели данных, но основные концепции и логику скрипта все равно можно использовать для автоматизации процессов для вашей организации. Например, вы можете не использовать правила проверки, и, соответственно изменить скрипт и удалить из него проверку с помощью правил. Также, в ряде случаев при использовании правил проверки вы можете захотеть согласовать, запустить проверку и закрепить изменения в каждой версии отдельно, перед запуском операции проверки, чтобы быть уверенным, что изменения, сделанные другими пользователями, будут включены в проверку.
В этом примере настройка данных следующая:
- Векторный веб-слой должен иметь включенную функцию синхронизации, содержать данные сервис-ориентированной версии, а также должен быть опубликован с включенным функционалом управления версиями, и с выбранной опцией Создать версию для каждой скачанной карты, это требует ArcGIS Enterprise не ниже версии 10.8.1.
- Реплики были созданы, когда карта, содержащая векторный веб-слой, находилась в автономном режиме
- У пользователя портала должны быть учетные данные участника либо с ролью администратора портала по умолчанию, либо с пользовательской ролью, которой предоставлены права доступа для управления версиями.
- В этом примере к данным также применены правила атрибутов проверки и включена функция сервера проверки. Это - не обязательное требование для работы с версиями реплик, но позволяет обеспечить целостность данных.
Ниже описаны шаги, которые необходимо пройти после того, как будут выполнены все необходимые условия:
- Список версий реплик для этого сервиса объектов (векторного веб-слоя) можно получить с помощью ресурса replicas в ArcGIS REST API.
- Используйте ресурс versionsInfos в ArcGIS REST API для получения свойств этой версии.
Используя эти свойства, создайте фильтр, чтобы получить только те версии, в которых дата оценки равна нулю или измененная дата больше последней даты оценки (то есть с момента последней оценки были сделаны изменения). Добавьте имена версий, удовлетворяющие фильтру, в список listOfVersionsToValidate, который будет оцениваться.
- Для каждой версии в списке оценки используйте операциюevaluate в ArcGIS REST API, чтобы выполнить оценку правил атрибутов проверки в этом сервисе.
Если оценка прошла успешно без возвращенных ошибок, то версия реплики готова к согласованию и публикации. Если оценка прошла успешно, но ошибки возвращаются, не публикуйте изменения и создайте сообщение, чтобы ошибки можно было проверить и исправить вручную.
- Для версий реплик, которые были успешно оценены без ошибок, запустите инструмент Согласовать версии с возможностью публикации изменений.
- Запустите инструмент Согласовать версии с возможностью только согласования (без публикации) на всех версиях реплик.
Образец кода
Приведенный ниже образец кода 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.')