I have a multitude of layers in an ArcPro map that I want to upload to AGOL using ArcPy. The following code will upload each layer that includes the name "zone" to a folder in AGOL. However, when I open the layer in AGOL, I see that it actually contains all the data from all other layers too (see screenshots). How can I have the code explicitly reference a single layer in my map?
prj = arcpy.mp.ArcGISProject(prjPath)
m = prj.listMaps('Map')[0]
lyr_zone = m.listLayers()
for l in lyr_zone:
if 'zone' in l.name:
print (l.name)
service = l.name
# Local paths to create temporary content
outdir = r"C:\\10000_VGF\VGF soil zones\Temp"
sddraft_filename = os.path.join(outdir, service + ".sddraft")
sddraft = m.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", service)
sddraft.summary = "Soil zones created using Veris technology for VGF"
sddraft.tags = "soil, zones"
# Create Service Definition Draft file
print("Creating SD file")
sddraft.exportToSDDraft(sddraft_filename)
# Stage Service
print("Creating Stage Service file")
sd_filename = os.path.join(outdir, service + ".sd")
arcpy.StageService_server(sddraft_filename, sd_filename)
# Share to portal
print("Uploading Service Definition...")
arcpy.UploadServiceDefinition_server(sd_filename, "My Hosted Services", in_folder_type = "Existing", in_folder = "Soils", in_organization = "SHARE_ORGANIZATION")
print("Successfully Uploaded service.")
Solved! Go to Solution.
The syntax for the getWebLayerSharingDraft method is as follows (from documentation😞
getWebLayerSharingDraft (server_type, service_type, service_name, {layers_and_tables})
note the final parameter is used to specify what layers/tables to publish. The default is to publish all layers/tables in the specified map, which is what is happening in your case.
Thank you so much. The final parameter is what I was missing. I thought by putting in the service name it would map the layer. I edited the original code below to show where I added in the specific layer.
prj = arcpy.mp.ArcGISProject(prjPath)
m = prj.listMaps('Map')[0]
lyr_zone = m.listLayers()
for l in lyr_zone:
if 'zone' in l.name:
print (l.name)
service = l.name
# Local paths to create temporary content
outdir = r"C:\\10000_VGF\VGF soil zones\Temp"
sddraft_filename = os.path.join(outdir, service + ".sddraft")
sddraft = m.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", service, l)
Layer—ArcGIS Pro | Documentation
either provide its positional index number or its name as in the code examples
m = p.listMaps()[0] # first map
l = m.listLayers()[0] # first layer or [2] for 3rd layer
Hi Dan,
I have read through the documentation multiple times to try to get a handle on what listLayers does and what it will return. I need the program to iterate through the layers in my ArcPro doc and publish them separately, which is not really happening. From the documentation, the listLayers gives an object at a location, as shown below.
Using the code I first posted, I can get it to list the names using the filter criteria, but when the layer gets published, it actually publishes the data from all layers under that one name, and this repeats for each layer. The second picture in the original post shows the layer "22 acres zones - XXX zones" in a web map. This layer contains the geometry and name of all other fields under the heading of "22 acres zones". This is where I get confused about what exactly I am calling and how the data is being read to be published.
I think you are iterating through layers correctly. The problem might simply be that the service is being defined by the map rather than the layer, so you're getting the contents of the map:
sddraft = m.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", service)
The only solution I can think of is to copy each layer to a new map (either the same empty map and add/delete layers as you go, or a separate map for each), which I've never attempted. Maybe someone else knows a better approach.
edited for clarity
The syntax for the getWebLayerSharingDraft method is as follows (from documentation😞
getWebLayerSharingDraft (server_type, service_type, service_name, {layers_and_tables})
note the final parameter is used to specify what layers/tables to publish. The default is to publish all layers/tables in the specified map, which is what is happening in your case.
Thank you so much. The final parameter is what I was missing. I thought by putting in the service name it would map the layer. I edited the original code below to show where I added in the specific layer.
prj = arcpy.mp.ArcGISProject(prjPath)
m = prj.listMaps('Map')[0]
lyr_zone = m.listLayers()
for l in lyr_zone:
if 'zone' in l.name:
print (l.name)
service = l.name
# Local paths to create temporary content
outdir = r"C:\\10000_VGF\VGF soil zones\Temp"
sddraft_filename = os.path.join(outdir, service + ".sddraft")
sddraft = m.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", service, l)