Update Service Definition on AGOL

3702
6
Jump to solution
01-05-2018 01:59 PM
MikeHay
New Contributor II

Using the script at this blog: https://blogs.esri.com/esri/arcgis/2017/03/14/updating-your-hosted-feature-services-with-arcgis-pro-...

Line 41: sdItem = gis.content.search("{} AND owner:{}".format(sd_fs_name, user), item_type="Service Definition")[0]
returns the wrong Service Definition (SD). The title query is not strict enough, so it returns any SD with a "Z" in the title. The SD I'm looking for is Zoning.

Title or owner can be replaced with id:
sdItem = gis.content.search(query="title:"+ sd_fs_name + " AND id:" + serviceItemID, item_type= "Service Definition")[0]
which throws: IndexError: list index out of range


Many permutations have been tried for using ID.

If item_type= "Service Definition" is removed, line 41 will run:
sdItem = gis.content.search(query="title:"+ sd_fs_name + " AND id:" + serviceItemID)[0]

However, then on line 45: fs = sdItem.publish(overwrite=True)
it throws:
File “C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\gis.py”, line 3125, in publish
if fileType == ‘shapefile’:
UnboundLocalError: local variable ‘fileType’ referenced before assignment

So, the question is - how do I specify the ID, and also specify the item type?

0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable

Mike Hay wrote:

Thanks Aaron,

There's still the problem that the line gis.content.search won't run if type is specified, but if type is not specified then the sdItem.publish errors out.

It sounds like the query you are creating is returning no items. The search function returns a list of items. Since no items are returned, and you are accessing it via an index of 0, you get the "list index out of range error". 

The itemId you need to specify should be the item id of the service definition file on AGOL, not the id of the published service. Can you verify the item id points to a service definition file on AGOL?

View solution in original post

0 Kudos
6 Replies
by Anonymous User
Not applicable

A query like the following should work

type:"Service Definition" id:b7ec249e81b7405bd5322adee43d8feb

There isn't really a need to specify the type and the id though, since the item id alone is unique.

The following both return the same item.

sdItem = gis.content.search('type:"Service Definition" id:b7ec249e81b7405bd5322adee43d8feb')[0]

sdItem = gis.content.search('id:b7ec249e81b7405bd5322adee43d8feb')[0]

MikeHay
New Contributor II

Thanks Aaron,

There's still the problem that the line gis.content.search won't run if type is specified, but if type is not specified then the sdItem.publish errors out.

Here is the error for including both type and id, as formatted in your response, with the one difference of passing in the id as a variable:

---------------------------------------------------

pydev debugger: starting (pid: 11304)
Creating SD file
Connecting to http://www.arcgis.com
Search for original SD on portal...

File "C:\GIS\PROJECTS\PLANNING\UpdateZoning&GPToMatchNewParcels\updateAGOL_Pro.py", line 109, in <module>
update("Zoning", "f78c18c992e74846806fc7dc98fb66f8")
File "C:\GIS\PROJECTS\PLANNING\UpdateZoning&GPToMatchNewParcels\updateAGOL_Pro.py", line 76, in update
sdItem = gis.content.search('type:"Service Definition" id:' + serviceItemID)[0]
IndexError: list index out of range


Here is the error when fileType is not specified:

------------------------------------------------------------------------
pydev debugger: starting (pid: 7432)
Creating SD file
Connecting to http://www.arcgis.com
Search for original SD on portal...
Found SD: Zoning, ID: f78c18c992e74846806fc7dc98fb66f8
Uploading and overwriting...
Overwriting existing feature service...

File "C:\GIS\PROJECTS\PLANNING\UpdateZoning&GPToMatchNewParcels\updateAGOL_Pro.py", line 110, in <module>
update("Zoning", "f78c18c992e74846806fc7dc98fb66f8")
File "C:\GIS\PROJECTS\PLANNING\UpdateZoning&GPToMatchNewParcels\updateAGOL_Pro.py", line 101, in update
fs = sdItem.publish(overwrite=True)
File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\gis.py", line 3125, in publish
if fileType == 'shapefile':
UnboundLocalError: local variable 'fileType' referenced before assignment

0 Kudos
by Anonymous User
Not applicable

Mike Hay wrote:

Thanks Aaron,

There's still the problem that the line gis.content.search won't run if type is specified, but if type is not specified then the sdItem.publish errors out.

It sounds like the query you are creating is returning no items. The search function returns a list of items. Since no items are returned, and you are accessing it via an index of 0, you get the "list index out of range error". 

The itemId you need to specify should be the item id of the service definition file on AGOL, not the id of the published service. Can you verify the item id points to a service definition file on AGOL?

0 Kudos
MikeHay
New Contributor II

That was it! The ID that was being passed in was for the feature layer, not the service definition. Thanks Aaron!

0 Kudos
JacobMattison
New Contributor

Could you post what the final code looks like? Thanks!

0 Kudos
MikeHay
New Contributor II

import arcpy
import os, sys

from arcgis.gis import GIS

def update(planningLayer, serviceItemID):

# Set the path to the project
prjPath = r"\\server\ServiceProjects\Planning\\" + planningLayer + ".aprx"

# Feature service/SD name in arcgis.com, user/password of the owner account
sd_fs_name = planningLayer
portal = "http://www.arcgis.com" # Can also reference a local portal
user = ""
password = ""

# Set sharing options
shrOrg = True
shrEveryone = True
shrGroups = ""

# Local paths to create temporary content
relPath = sys.path[0]
sddraft = os.path.join(relPath, planningLayer + ".sddraft")
sd = os.path.join(relPath, planningLayer + ".sd")

# Create a new SDDraft and stage to SD
print("Creating SD file")
arcpy.env.overwriteOutput = True
prj = arcpy.mp.ArcGISProject(prjPath)
mp = prj.listMaps()[0]
arcpy.mp.CreateWebLayerSDDraft(mp, sddraft, sd_fs_name, 'MY_HOSTED_SERVICES', 'FEATURE_ACCESS','', True, True)
arcpy.StageService_server(sddraft, sd)

print("Connecting to {}".format(portal))
gis = GIS(portal, user, password)

# Find the SD, update it, publish /w overwrite and set sharing and metadata
print("Search for original SD on portal...")

sdItem = gis.content.search('id:' + serviceItemID)[0]

print("Found SD: {}, ID: {} \n Uploading and overwriting...".format(sdItem.title, sdItem.id))
#print("Found SD: {}, ID: {} \n Uploading and overwriting...".format(sdItem.id))
sdItem.update(data=sd)
print("Overwriting existing feature service...")
fs = sdItem.publish(overwrite=True)

if shrOrg or shrEveryone or shrGroups:
print("Setting sharing options...")
fs.share(org=shrOrg, everyone=shrEveryone, groups=shrGroups)

print("Finished updating: {} - ID: {}".format(fs.title, fs.id))

0 Kudos