Automatisieren von Abgleich- und Zurückschreibevorgängen für nach Verzweigung versionierte Daten mit aktivierter Synchronisierung

Mit der Standard- oder Advanced-Lizenz verfügbar.

Versionsadministratoren können Python-Skripte verwenden, um einen geplanten Abgleich von Replikatversionen zu automatisieren, nachdem Außendienstmitarbeiter ihre Änderungen an Daten in Verzweigungsversionierung synchronisiert haben.

Dieser Workflow kann für das Verwalten von Replikatversionen verwendet werden, die mit einem Web-Feature-Layer (Feature-Service) mit aktivierter Synchronisierung mit nach Verzweigung versionierten Daten erstellt wurden.

Weitere Informationen zum Arbeiten mit Offline-Karten mit nach Verzweigung versionierten Daten

Hinweis:

Dieser Workflow gilt speziell für die Verzweigungsversionierung. Die traditionelle Versionierung erfordert andere Verwaltungsaufgaben. Wenn Sie die traditionelle Versionierung verwenden, können Sie auch Abgleich- und Zurückschreibevorgänge mit Python automatisieren.

Anwendbares Szenario

Im Python-Beispiel im nächsten Abschnitt werden die ArcGIS REST API- und ArcPy-Funktionen des Feature-Service verwendet, um Replikatversionen mit vorhandenen Validierungsattributregeln abzugleichen und zurückzuschreiben. Nachfolgend wird beschrieben, wann das Codebeispiel verwendet werden sollte und welche Operationen das Beispielskript ausführt.

Hinweis:

Dieses Skript ist ein Beispiel für einen Workflow mit einem bestimmten Daten-Setup. Ihre Workflows entsprechen möglicherweise nicht genau diesem Datenmodell, die Konzepte und die Logik des Skripts können aber dennoch verwendet werden, um ein angepasstes automatisiertes Skript für Ihre Organisation zu erstellen. Wenn Sie beispielsweise keine Validierungsregeln verwenden, können Sie das Skript ändern, um die Auswertung von Validierungsregeln zu entfernen. Es kann auch vorkommen, dass Sie bei Verwendung von Validierungsregeln alle Versionen abgleichen, validieren und einzeln zurückschreiben möchten, bevor Sie die Auswertungsoperation durchführen, um sicherzustellen, dass die Validierung die von den anderen Editoren vorgenommenen Änderungen umfasst.

Voraussetzung:

In diesem Beispiel wird die folgende Konstellation verwendet:

  • Der Web-Feature-Layer muss für die Synchronisierung aktiviert sein, nach Verzweigung versionierte Daten enthalten, mit aktivierter Funktion "Versionsverwaltung" veröffentlicht worden sein, und die Option Für jede heruntergeladene Karte eine Version erstellen muss aktiviert sein. Dazu ist ArcGIS Enterprise 10.8.1 oder höher erforderlich.
  • Replikate wurden erstellt, als eine Karte, die den Web-Feature-Layer enthält, offline genommen wurde.
  • Die Anmeldeinformationen, die für den Portal-Benutzer im Skript angegeben sind, müssen für ein Mitglied der Standardadministratorrolle des Portals oder einer benutzerdefinierten Rolle mit der Berechtigung zur Versionsverwaltung gelten.
  • In diesem Beispiel wurden in den Daten auch Validierungsattributregeln angewendet und die Funktionalität des Validierungsservers aktiviert. Dies ist zwar keine Voraussetzung für die Arbeit mit Replikatversionen, bietet aber eine Möglichkeit, die Datenintegrität zu gewährleisten.

Im Folgenden werden die Schritte zusammengefasst, die Sie in das Skript aufnehmen, nachdem Sie sichergestellt haben, dass die Voraussetzungen erfüllt sind:

  1. Verwenden der Ressource replicas in ArcGIS REST API zum Abrufen einer Liste der Replikatversionen für den Feature-Service (Web-Feature-Layer).
  2. Verwenden der Ressource versionsInfos in ArcGIS REST API zum Abrufen der Eigenschaften der Version.

    Verwenden dieser Eigenschaften zum Erstellen eines Filter, damit nur die Versionen abgerufen werden, in denen das Auswertungsdatum NULL ist oder das Datum der letzten Änderung größer als das Datum der letzten Auswertung ist (was bedeutet, dass seit der letzten Auswertung Änderungen vorgenommen wurden). Anhängen der Namen der Versionen, die den Filter erfüllen, an die Liste listOfVersionsToValidate mit den Versionen, die ausgewertet werden sollen.

  3. Verwenden der Operation evaluate in ArcGIS REST API für jede Version in der Auswertungsliste zum Auswerten der Validierungsattributregeln im Service.

    Wenn die Auswertung erfolgreich war und keine Fehler zurückgegeben wurden, kann die Replikatversion abgeglichen und zurückgeschrieben werden. Wenn die Auswertung erfolgreich war, aber Fehler zurückgegeben wurden, dürfen die Änderungen nicht zurückgeschrieben werden. Stattdessen wird eine entsprechende Meldung generiert, damit die Fehler manuell untersucht und korrigiert werden können.

  4. Ausführen des Werkzeugs Versionen abgleichen mit der Option zum Zurückschreiben der Änderungen für Replikatversionen, die erfolgreich und ohne Fehler ausgewertet wurden.
  5. Ausführen des Werkzeugs Versionen abgleichen mit der Option zum ausschließlichen Abgleichen (ohne Zurückschreiben) für alle Replikatversionen.

Codebeispiel

Das folgende Python-Codebeispiel führt die oben angegebenen Operationen aus. Dieses Skript enthält eine Option zum Generieren einer Protokolldatei, in der die Ausgabe jeder ausgeführten Operation erfasst wird und die nach der Ausführung des Skripts angezeigt werden kann.

# 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.')

Verwandte Themen