3

I am having a bit of trouble with Python. I am trying to create a script (hard-coded for now, but eventually soft-coded to make a script tool) that allows the user to back up layers of a given map in ArcGIS Pro by creating local feature classes in a new file geodatabase named with today's date. Here is my script:

import arcpy

arcpy.env.overwriteOutput = True

Project = r"P:\Projects\MyProject.aprx"outPath = r"P:\Projects"
myProj = arcpy.mp.ArcGISProject(Project)
myMap = myProj.listMaps("Map")[0]

today = datetime.date.today()
date = today.strftime("%Y%m%d")
name = "Backup_" + str(date) + ".gdb"
arcpy.CreateFileGDB_management(outPath, name)
GDB = outPath + "\\" + name

for layer in myMap.listLayers():  
    arcpy.CopyFeatures_management(layer,GDB)

My script keeps failing in the Python console, and I get the message: "arcgisscripting.ExecuteError: Failed to execute. Parameters are not valid. ERROR 000840: The value is not a Feature Layer. Failed to execute (CopyFeatures)."

My understanding is that listLayers creates a layer object, but to use Copy Features I need a feature layer. I've tried re-writing the 'for' loop to make a feature layer as follows:

for layer in myMap.listLayers(): 
    Feat = arcpy.MakeFeatureLayer_management(layer,"Templayer")
    arcpy.CopyFeatures_management(Feat,GDB)

However, I get the same error.

My layers are all web-hosted, although I don't know if this is the cause of my problem. I really want a script that allows me to select a map within ArcGIS Pro, loop through all layers in the map, and copy them into a new FGDB.

How can I get my script to work?

Is there a way to convert a layer object into a feature layer?

Am I using the wrong approach?

5
  • Welcome to GIS SE! As a new use please take the tour
    – Midavalo
    Commented Apr 30, 2020 at 17:02
  • My layers are all web-hosted, although I don't know if this is the cause of my problem - what happens if you run the geoprocessing tool Copy Features directly on one of your layers (ie from the ArcGIS Pro tool, not from the script)? Does the tool run on your layer?
    – Midavalo
    Commented Apr 30, 2020 at 17:03
  • 2
    Have you considered simplifying and just using the Package Map tool?
    – KHibma
    Commented Apr 30, 2020 at 17:05
  • Yes, Copy Features runs on the layers no problem when I use that tool. However, if I want to automate the process or soft-code the script, I need to be able to run Copy Features multiple times, but would like control over which map contains the features I'd like to backup.
    – dgray
    Commented Apr 30, 2020 at 17:41
  • I just tested the Package Map tool. Unfortunately, the packaged map only contains pointers to the web layers rather than copies of the layers as I would like to create. I would like to create physical duplicate copies of my web layers.
    – dgray
    Commented Apr 30, 2020 at 17:48

3 Answers 3

1

Maybe the error "The value is not a Feature Layer" is coming from the online basemap layers, are they still in the map, like "World Topographic Map"? Or any non-feature layers that CopyFeatures_management does not work with?

Maybe check the layer type in the loop (as below)? Maybe add a print statement just so you know which is failing?

for layer in myMap.listLayers():    
    print(layer.name)
    if (layer.isFeatureLayer):
        arcpy.CopyFeatures_management(layer,GDB)

1

I managed to solve this issue and create a script (now softcoded so that it can be put into a script tool) that backs up all layers in an open ArcGIS Pro project and puts them into a new fgdb.

I was able to use the web layers by referencing their source URL, and using Feature Class to Feature Class instead of Copy Features, since it allows you to make your output name. It also assumes that your Esri-hosted web layers begin with "https://services6.arcgis.com" (I am not 100% if this rings true for everyone's Esri-hosted web layers).

This script can be made into a script tool intended to be run from within the relevant ArcGIS Pro project file, with three inputs:

  1. a File type parameter, pointing to the aprx file

  2. a Workspace type parameter, pointing to the directory where the backup will be created.

  3. a Map type parameter, referencing the web map, must be a map in your ArcGIS Pro project file, and should be updated to reflect the state of the AGOL web map prior to running.

It catches a few common invalid characters used in layer names (spaces, parentheses, hyphens, slashes, and periods). Any other invalid characters in the layer aliases will cause the script to fail. Also it assumes the layers have different names (repeating layer names will result in them being overwritten).

I am sharing the script in case it benefits anyone else.

# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------------
# Back Up All Web Map Layers.py
# Created on: 2020-04-30
# Written By: Dianne Gray
# Description:
# This model takes a selected web map in a selected ArcGIS Pro project file and 
# creates copies of all the input layers in a new file geodatabase
# Changes: Version 1
# ---------------------------------------------------------------------------

import arcpy

# To allow overwriting the outputs change the overwrite option to true.
arcpy.env.overwriteOutput = True

# Local variables:
# Input and Output Directories
Project = sys.argv[1]
outPath = sys.argv[2]
sourceMap = sys.argv[3]
myProj = arcpy.mp.ArcGISProject(Project)
myMap = myProj.listMaps(sourceMap)[0]

# Create name for backup GDB 
startName = sourceMap
mapName = startName.replace(" ", "_")
today = datetime.date.today()
date = today.strftime("%Y%m%d")
name = mapName + "_Backup_" + str(date) + ".gdb"

# Create the GDB for the output feature classes
arcpy.CreateFileGDB_management(outPath, name)
GDB = outPath + "\\" + name
arcpy.AddMessage("Created Backup File Geodatabase")

# Loop through layers in the map and create copies
for layer in myMap.listLayers():
    # Get the source path of web layer
    Source = layer.dataSource
    # Get the layer name
    lyrName = layer.name
    # Identify only the web layer (excluding web-hosted content like basemaps)
    if "https://services6.arcgis.com" in Source:
        # Get rid of invalid symbols in layer name if they're present
        if (" " or "/" or "(" or ")" or "." or "-") in lyrName:
            lyrName2 = lyrName.replace(" ", "_")
            lyrName3 = lyrName2.replace("/", "_")
            lyrName4 = lyrName3.replace("(", "_")
            lyrName5 = lyrName4.replace(")", "_")
            lyrName6 = lyrName5.replace(".", "")
            lyrName7 = lyrName6.replace("-", "_")
            newName = lyrName7
            # Write output feature class
            arcpy.FeatureClassToFeatureClass_conversion(Source, GDB, newName)
            arcpy.AddMessage("Backed up " + lyrName)
        else:
            newName = lyrName
            # Write output feature class
            arcpy.FeatureClassToFeatureClass_conversion(Source, GDB, newName)
            arcpy.AddMessage("Backed up " + lyrName)
arcpy.AddMessage("Backup is complete")
0

The hosted feature layers I added to ArcGIS Pro from Portal/AGOL were added as group layers. I needed to use the layer.listLayers() function on the group layer to retrieve the inner layer. This layer was recognized as a feature layer and could be used for the CopyFeatures_management function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.