Improving the speed of arcpy.ChangeVersion_management in ArcGIS Pro

1171
6
Jump to solution
07-14-2021 03:11 AM
MattHowe
Occasional Contributor

I'm creating a script that includes a section that appends a feature from the 'memory' workspace to a newly created version of our SDE.DEFAULT database. When running the script I've noticed that the arcpy.ChangeVersion_management geoprocessing tool is cripplingly slow, just to switch to the new version. In addition, appending one feature to the new version if also painfully slow. The code is below but does anyone have any ideas as to how it can be speeded up?

 

if upload_to_SDE == "true":
    arcpy.SetProgressorLabel("Preparing new SDE version")
    arcpy.AddMessage("Creating SDE version")
    try:
        arcpy.env.workspace = sde_path
        parent_version = "SDE.DEFAULT"
        version_name = "TEST_VERSION"
        sde_fl = "SurveyAreaFL"
        full_version_name = f"OPS${get_current_user()}.{version_name}"
        # Create new version for the new extent
        arcpy.CreateVersion_management(sde_path, parent_version, version_name, "PUBLIC")
        arcpy.AddMessage(f"Version: {full_version_name} created")
        arcpy.management.MakeFeatureLayer(survey_area_path, sde_fl)
        arcpy.SetProgressorLabel("Changing version")
        arcpy.ChangeVersion_management(sde_fl, "TRANSACTIONAL", full_version_name)
        arcpy.AddMessage(f"Version changed: ADM.SurveyArea {full_version_name}")
        arcpy.SetProgressorLabel("Appending features")
        arcpy.Append_management(r"memory\NewSurveyArea", sde_fl, "TEST")
        arcpy.AddMessage("Data appended to SDE: SurveyArea")
    except arcpy.ExecuteError:
        exec_error()
    except:
        traceback_error()

 

 

 

0 Kudos
2 Solutions

Accepted Solutions
MattHowe
Occasional Contributor

Hi @PhilLarkin1 , I found a workaround that seems fast. Create a new version then create a temporary connection file avoiding the slog of trying to change the version.

try:
    #  Check if version name already exists - use existing one if found or create a new one
    arcpy.SetProgressorLabel("Processing EGDB requirements")
    version_list = [sde_version.name for sde_version in arcpy.da.ListVersions(sde_path)]
    if full_version_name not in version_list:
        arcpy.AddMessage("Creating new version of sde.default")
        arcpy.CreateVersion_management(sde_path, parent_version, version_name, "PUBLIC")
    else:
        arcpy.AddMessage("Version already exists - writing to existing version")
    arcpy.AddMessage("Creating temporary connection file")
    #  Check if temp username folder exists, if not create in the staging area.
    #  The temp user folder is used to store the temp connection file.
    staging_user_folder_path = os.path.join(staging_folder, get_current_user())
    if not os.path.exists(staging_user_folder_path):
        os.mkdir(staging_user_folder_path)
    #  Create temporary connection file in the user folder that connects to the version
    arcpy.CreateDatabaseConnection_management(
        staging_user_folder_path, f"{version_name}.sde", "ORACLE",
        f"{os.path.basename(sde_path_split[0])}/{os.path.basename(sde_path_split[0])}", "OPERATING_SYSTEM_AUTH",
        None, None, None, None, None, "TRANSACTIONAL", full_version_name)
    temp_sde_path = os.path.join(staging_user_folder_path, f"{version_name}.sde")
    temp_sde_fc_path = os.path.join(temp_sde_path, sde_fs_fc_name)
except arcpy.ExecuteError:
    exec_error()
except:
    traceback_error()

 

View solution in original post

0 Kudos
PhilLarkin1
Occasional Contributor III

This method took about a minute, which is a vast improvement over changing the version per layer. Thanks for the suggestion!

I used updateConnectionProperties to change the version.

project = arcpy.mp.ArcGISProject("CURRENT")
map = project.listMaps(<mapName>)[0]
sdePath == "file\path\to\layer\sdefile"
editVersionConnFile = arcpy.management.CreateDatabaseConnection(out_folder_path = project.homeFolder, out_name = versionName, database_platform = "SQL_SERVER",instance = "<server>\\<instance>", account_authentication = "OPERATING_SYSTEM_AUTH",database = "<database>", version_type = "TRANSACTIONAL", version = versionName)
map.updateConnectionProperties(current_connection_info = sdePath, new_connection_info = editVersionConnFile)

 

View solution in original post

6 Replies
DanPatterson
MVP Esteemed Contributor

@KoryKramer 's post provides tips on performance problems

Troubleshooting Performance Issues in ArcGIS Pro - Esri Community

or Announcing the ArcGIS Pro Performance Assessment Tool (PAT) (esri.com)

other than that, working with Tech Support may be your remaining option.


... sort of retired...
0 Kudos
PhilLarkin1
Occasional Contributor III

I've noticed that ChangeVersion is very slow as well.

MattHowe
Occasional Contributor

Hi @PhilLarkin1 , I found a workaround that seems fast. Create a new version then create a temporary connection file avoiding the slog of trying to change the version.

try:
    #  Check if version name already exists - use existing one if found or create a new one
    arcpy.SetProgressorLabel("Processing EGDB requirements")
    version_list = [sde_version.name for sde_version in arcpy.da.ListVersions(sde_path)]
    if full_version_name not in version_list:
        arcpy.AddMessage("Creating new version of sde.default")
        arcpy.CreateVersion_management(sde_path, parent_version, version_name, "PUBLIC")
    else:
        arcpy.AddMessage("Version already exists - writing to existing version")
    arcpy.AddMessage("Creating temporary connection file")
    #  Check if temp username folder exists, if not create in the staging area.
    #  The temp user folder is used to store the temp connection file.
    staging_user_folder_path = os.path.join(staging_folder, get_current_user())
    if not os.path.exists(staging_user_folder_path):
        os.mkdir(staging_user_folder_path)
    #  Create temporary connection file in the user folder that connects to the version
    arcpy.CreateDatabaseConnection_management(
        staging_user_folder_path, f"{version_name}.sde", "ORACLE",
        f"{os.path.basename(sde_path_split[0])}/{os.path.basename(sde_path_split[0])}", "OPERATING_SYSTEM_AUTH",
        None, None, None, None, None, "TRANSACTIONAL", full_version_name)
    temp_sde_path = os.path.join(staging_user_folder_path, f"{version_name}.sde")
    temp_sde_fc_path = os.path.join(temp_sde_path, sde_fs_fc_name)
except arcpy.ExecuteError:
    exec_error()
except:
    traceback_error()

 

0 Kudos
PhilLarkin1
Occasional Contributor III

Oooh, good idea! Looking forward to trying this out.

0 Kudos
PhilLarkin1
Occasional Contributor III

This method took about a minute, which is a vast improvement over changing the version per layer. Thanks for the suggestion!

I used updateConnectionProperties to change the version.

project = arcpy.mp.ArcGISProject("CURRENT")
map = project.listMaps(<mapName>)[0]
sdePath == "file\path\to\layer\sdefile"
editVersionConnFile = arcpy.management.CreateDatabaseConnection(out_folder_path = project.homeFolder, out_name = versionName, database_platform = "SQL_SERVER",instance = "<server>\\<instance>", account_authentication = "OPERATING_SYSTEM_AUTH",database = "<database>", version_type = "TRANSACTIONAL", version = versionName)
map.updateConnectionProperties(current_connection_info = sdePath, new_connection_info = editVersionConnFile)

 

MattHowe
Occasional Contributor

Great stuff!

0 Kudos