CODE SNIPPETS THAT UTILISE THE OVERWRITEFS PYTHON MODULE FOR UPDATING AND MANAGING VIEW RELATIONSHIPS. THIS IS NOT A FULL PROGRAM BUT JUST BITS AND PIECES. # Determine which feature service (A or B version) is the target for updating info("Identifying the target hosted layer for view {}".format(hostsedview)) agolitem = gis.content.search(query=hostsedview, item_type="Feature Layer") x = 0 viewitem = None for searchresult in agolitem: if searchresult["title"] == hostsedview: viewitem = agolitem[x] break else: x = x + 1 if viewitem is None: msg = '**** Error : Hosted view name {} was not found on ArcGIS Online. ' msg = msg + ' view: ' + hostsedview + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False try: outcome = OverwriteFS.getFeatureServiceTarget(viewitem, verbose=max, outcome={"success": None, "items": []}, ignoreDataItemCheck=False) if outcome is None: msg = '**** Error determining the target hosted layer for deleting (by chunk method).' msg = msg + 'Feature Service view: ' + hostsedview + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False except: msg = '***** Error determining the target hosted layer for deleting (by chunk method).' msg = msg + ' Feature Service view: ' + hostsedview + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False # Get item details of Target service. In this case "view" means the idle target item if "view" in outcome: targetitem = outcome["view"] else: msg = '***** Error determining the target hosted layer for deleting (by chunk method).' msg = msg + ' Feature Service view: ' + hostsedview + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False ----------------------- # Delete rows in the Target layer (by chunks) # Get max number of features time.sleep(5) layerIndex = 0 fLyr = targetitem.layers[layerIndex] try: max_objid = fLyr.query(out_statistics=[ \ {"statisticType": "MAX", "onStatisticField": "objectid", \ "outStatisticFieldName": "MAX_OBJ"}], return_geometry=False) maxoid = max_objid.features[0].attributes['MAX_OBJ'] SMaxOID = str(maxoid) info("{} max Object ID is {}".format(targetitem.title, SMaxOID)) except: msg = '***** Error determining the maximum object ID of feature service : ' msg = msg + targetitem.title + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False # Delete individual features in chunks of 10000 info("Deleting hosted layer records by chunks for service : {0}".format(targetitem.title)) time.sleep(5) i = 0 step = 10000 if maxoid is not None: while i <= maxoid : i += step try: #fLyr.delete_features(where=f"OID<= {i}") fLyr.delete_features(where=f"objectid<= {i}") except: msg = '***** Error deleting a chunk of records in Feature Service: ' msg = msg + targetitem.title + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False info("Deleted records with chunk method. Max ObjectID processed: {}, Service: {}".format(i,targetitem.title)) #### END OF DELETE BY CHUNKS --------------------------------------- # Truncating Feature Service Before Append to avoid growing object id values info("Truncating feature service..") time.sleep(5) try: fLyr.manager.truncate() except: msg = '***** Error truncating Feature Service: ' + targetitem.title msg = msg + ' .. WARNING: THIS FEATURE SERVICE IS NOW EMPTY !!!! Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False else: info("Feature Layer {} was empty..Proceeding with Append".format(targetitem.title)) --------------------------------------------------- # Append the data from the source file Gdb onto target hosted layer info("Appending features from temp File Geodatabase onto service {}".format(targetitem.title)) time.sleep(5) # fieldmappings = [{"parcelnum": "parcelnum", # "dcdb_id": "dcdb_id", # "parcel_number": "parcel_number", # "seq_num": "seq_num", # "unit_num": "unit_num", # "street_num": "street_num", # "street_num_formatted_incunit": "street_num_formatted_incunit", # "street_name": "street_name", # "street_type": "street_type", # "suburb": "suburb", # "state": "state", # "postcode": "postcode", # "parcel_address": "parcel_address", # "address_noext": "address_noext", # "parcel_address_full": "parcel_address_full", # "lga": "lga" # }] try: #fLyr.append(item_id=datastore_item.id, upsert=False, field_mappings=fieldmappings) fLyr.append(item_id=source_itemid, upload_format="filegdb", upsert=False, field_mappings=[]) except: msg = '**** Error appending records from Uploaded File Gdb onto {}'.format(targetitem.title) msg = msg + ' .. WARNING: THIS FEATURE SERVICE IS NOW EMPTY !!!! Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) return False ----------------------------------------------------------------------- # Touch the target feature service to update it's last modified date # (Does not overwrite as we have not listed an updateFile) info("Updating date modified on feature service {} ".format(targetitem.title)) time.sleep(5) try: outcome = OverwriteFS.overwriteFeatureService(targetitem, updateFile=None, touchItems=True, verbose=None, touchTimeSeries=True, outcome=None, ignoreItems=[], serviceLastModified=0, noIndexes=False, preserveProps=True, noWait=False, noProps=False, converter=None, outPath="", dryRun=False, ignoreAge=False) if outcome is None: msg = '***** Error updating modified date on Feature Service: ' + targetitem.title msg = msg + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) deletegdbs(gis) return False except: msg = '***** Error updating modified date on Feature Service: ' + targetitem.title msg = msg + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) deletegdbs(gis) return False -------------------------------------------------------------------------------- # Swap the Current and Target layers for the service's view # Uses the swapFeatureViewLayers function that would normally overwrite the target layer, however in this case, we are not # specifying a source, so the overwrite is ignored, however it still continues to swap the target and current layers around # so the view points to the newly refreshed layer. # This also backs up the service's properties (eg. Summary, Tag etc) and restores it back to the service info('Swapping Target and Current layers for view {} '.format(hostsedview)) time.sleep(5) dry_run = False # Only set dry_run true for test mode where it verifies everything without making an overwrite or swapping try: outcome = OverwriteFS.swapFeatureViewLayers(viewitem, updateFile=None, touchItems=True, verbose=True, \ touchTimeSeries=False, outcome=None, noIndexes=True,preserveProps=False, noWait=False,noProps=True, \ converter=None, outPath="", dryRun=False, noSwap=False, ignoreAge=False) if outcome is None: msg = '***** Error swapping Target and Current layers for view {}'.format(hostsedview) msg = msg + ' after appending new data to Target Feature Service .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) deletegdbs(gis) return False else: info('Target and Current Layers successfully swapped for view : {}'.format(hostsedview)) except: msg = '***** Error swapping Target and Current layers for view {} after appending new data to Target Feature Service: '.format(hostsedview) msg = msg + ' .. Moving to next layer in list.' error(msg) email_flag = send_email(FailureSubject, msg) deletegdbs(gis) return False # For testing purposes just to check swap was successful : #info ('\nListing the new target below....') #outcome = OverwriteFS.getFeatureServiceTarget(viewitem, max, { "success": None, "items": []}, False) return True ------------------------------------------------------------------------ # Delete Uploaded File Geodatabases. (All FGDBs owned by this user.) info("Deleting all uploaded File Geodatabases....") import shutil global source_tempgdbpath global email_flag global username uname = 'owner:' + username try: agolgdb = gis.content.search(query=uname, item_type="File Geodatabase") if len(agolgdb) > 0: # print(agolgdb) for item in agolgdb: item.delete() except: msg = '***** Error attempting to locate File GDBs on AGOL. Moving to next layer in list' error(msg) email_flag = send_email(FailureSubject, msg) # Delete temporary File Geodatabases and zip files info("Deleting all temporary FGD and zip files....") dir = source_tempgdbpath for files in os.listdir(dir): path = os.path.join(dir, files) print('path= ' +path) # removes files and subfolders too try: shutil.rmtree(path) print('rmtree success') except: try: os.remove(path) print('remove success') except OSError: msg = '**** Error attempting to delete temp File GDBs and zip files from ' + source_tempgdbpath + \ ' Moving to next layer in list' error(msg) email_flag = send_email(FailureSubject, msg) return False