[GIS] How to extract the data showed in Version Changes before reconcile/post process

arcpypythonreconcileversioning

I want to make a script in python to extract the data about version changes before make the reconcile/post process. Is that possible? I trying to avoid use C# or VB script.

Best Answer

Here's a python script to try. It's designed to be set up and run as an ArcGIS Toolbox script. Parameter type info is commented in the code. This will take an input dataset and target dataset (which correspond to the dataset form the input and target Versions that you are reconciling). You will need to make a database connection to each Version and use those connections when adding the datasets as parameters. The script will compare the current geometry and attribution for each Version and produce a csv output file which lists the OBJECTID, type of change, and for attribute changes the field and values. It will find adds, deletes, geometry updates and attribute updates. I've only tested this on a small dataset with "contrived" edits for testing, but hopefully it will work for you as well.

import arcpy, os

inputDataset = arcpy.GetParameterAsText(0)    # Parameter Type = Feature Class
targetDataset = arcpy.GetParameterAsText(1)   # Parameter Type = Feature Class
outputFolder = arcpy.GetParameterAsText(2)    # Parameter Type = Folder
outputName = arcpy.GetParameterAsText(3)      # Parameter Type = String

inputDict = {}
changes = []

# GET FIELDS
arcpy.AddMessage("Getting Fields\n")
fields = ["OID@", "Shape@JSON"]
fieldList = arcpy.ListFields(targetDataset)
for field in fieldList:
    if field.name not in ("OBJECTID", "SHAPE", "Shape_Length", "Shape_Area", "RuleID", "Override"):
        fields.append(field.name)

# SEARCH INPUT DATASET, ADD DATA TO DICTIONARY
arcpy.AddMessage("Searching Input Dataset\n")
with arcpy.da.SearchCursor(inputDataset, fields) as inputRows:
    for inputRow in inputRows:
        oid = inputRow[0]
        geom = inputRow[1]
        attrs = {"Geometry":geom}
        for i in range(len(fields)):
            if i > 1:
                field = str(fields[i])
                attrs[field] = inputRow[i]
        inputDict[oid] = attrs

# SEARCH TARGET DATASET AND COMPARE TO DICTIONARY DATA
arcpy.AddMessage("Searching Target Dataset\n")
with arcpy.da.SearchCursor(targetDataset, fields) as targetRows:
    for targetRow in targetRows:

        # If no match in dictionary, it's a delete
        oid = targetRow[0]
        if oid not in inputDict.keys():
            changes.append([oid, "Delete", "N/A", "N/A", "N/A"])
        else:

            # If geometries don't match, it's a geometry update
            geom = targetRow[1]
            if geom != inputDict[oid]["Geometry"]:
                changes.append([oid, "Geometry Update", "N/A", "N/A", "N/A"])

            # If attribute values don't match, it's an attribute update
            for j in range(len(fields)):
                if j > 1:
                    field = str(fields[j])
                    value = targetRow[j]
                    if value != inputDict[oid][field]:
                        changes.append([oid, "Attribute Update", field, value, inputDict[oid][field]])

            # If there was a match, remove item from dictionary
            del inputDict[oid]

# Anything left in the dictionary is an added feature
for oid in inputDict.keys():
    changes.append([oid, "Add", "N/A", "N/A", "N/A"])


# Write Output Change File
arcpy.AddMessage("Writing Output File\n")
outputFile = open(outputFolder + os.sep + outputName + ".csv", "w")
outputFile.write("OID,CHANGETYPE,FIELD,INPUTVALUE,TARGETVALUE\n")
for change in changes:
    line = ""
    for item in change:
        line += str(item)
        line += ","
    line = line[:-1]
    line += "\n"
    outputFile.write(line)

arcpy.AddMessage("\n\nAll Done!\n\n")
Related Question