Updating Feature layer using ArcGIS API for python.

4003
7
Jump to solution
09-16-2020 08:11 PM
Server
by
New Contributor II

Hello! Im new to PythonAPI, still very much a novice. I'm trying to update some fields in an AGO feature layer from a script. Hopefully I will be able to set up a reoccurring task which will update the layer consistently. Every time the task will run I want my script to look at a field, and change another field based on what is there. 

The change will occur based on a FromDate and a ToDate field. These fields will be the cause of the edit, which will change a field from Vacant to Occupied, depending if the current time (now()) falls within the FromDate / ToDate times. In other words, When the current time is After the FromDate and before the ToDate, the field will be occupied. 

This is what I have so far:

from arcgis.gis import GIS
from arcgis.features import FeatureSet, Feature

gis = GIS(url='https://pythonapi.playground.esri.com/portal', username='XXXXXX', password='XXXXXX')
itemId = 'xxxxxxxxxxxxxxxxxx'
fs=gis.content.get(itemId)


fl=fs.layers[0]

#this is where I get confused

features = not sure what to put here

for feature in features:
 if FromDate <= Now() and ToDate >= Now():
 newValue = 'occupied'
 
 feature.set_value('roomstatus',NewValue)
 else:
 newValue2 = 'vacant'
 feature.set_value('roomstatus',NewValue)


# update the features in AGOL
results = fl.edit_features(updates=features)
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Again, super new to this so any advice would be appreciated! Thanks. 
0 Kudos
1 Solution

Accepted Solutions
MehdiPira1
Esri Contributor

Hi Connor Vincent‌,

Here's the script that updates a feature layer/service attribute (room status) based on the current date, start date and end date. You just need to change the variables first.

from arcgis import GIS
import datetime

gis = GIS('url', 'username', 'password', verify_cert=False)

#search for the feature layer/service
featureLayer_item = gis.content.search('type: "Feature Service" AND title:"xxxxxxxx"')
#access the item's feature layers
feature_layers = featureLayer_item[0].layers
flayer = feature_layers[0]
#query all the features and get the spatial dataframe
fset = feature_layers[0].query()
flayer_rows = fset.sdf

# Updating feature service's attribute based on the current date, start date and end date
for index, row in flayer_rows.iterrows():
    today = datetime.datetime.today()
    if row['start_date'] <= today <= row['end_date']:
        print("Updating feature layer ....")
        fset.features[0].attributes['roomstatus'] = 'Vacant'
        flayer.edit_features(updates = fset.features) 
        print("Feature layer is set to Occupied!")
    else:
        print("Updating feature layer ....")
        fset.features[0].attributes['roomstatus'] = 'Occupied'
        flayer.edit_features(updates = fset.features) 
        print("Feature layer is set to Vacant!")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

7 Replies
MehdiPira1
Esri Contributor

Hi Connor Vincent‌,

Here's the script that updates a feature layer/service attribute (room status) based on the current date, start date and end date. You just need to change the variables first.

from arcgis import GIS
import datetime

gis = GIS('url', 'username', 'password', verify_cert=False)

#search for the feature layer/service
featureLayer_item = gis.content.search('type: "Feature Service" AND title:"xxxxxxxx"')
#access the item's feature layers
feature_layers = featureLayer_item[0].layers
flayer = feature_layers[0]
#query all the features and get the spatial dataframe
fset = feature_layers[0].query()
flayer_rows = fset.sdf

# Updating feature service's attribute based on the current date, start date and end date
for index, row in flayer_rows.iterrows():
    today = datetime.datetime.today()
    if row['start_date'] <= today <= row['end_date']:
        print("Updating feature layer ....")
        fset.features[0].attributes['roomstatus'] = 'Vacant'
        flayer.edit_features(updates = fset.features) 
        print("Feature layer is set to Occupied!")
    else:
        print("Updating feature layer ....")
        fset.features[0].attributes['roomstatus'] = 'Occupied'
        flayer.edit_features(updates = fset.features) 
        print("Feature layer is set to Vacant!")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
MehdiPira1
Esri Contributor

Hi Connor Vincent‌,

Could you please mark it as answered if it answered your question?

Thanks.

0 Kudos
Server
by
New Contributor II

Thank you! This seems to run without issue...it moves through the rows (I had to change the 'vacant' to 'occupied' and vise versa for the logic to work), yet I do not see any change in my data once complete. The "last updated" text reflects this (it changes every time the script is run), just no change in the data. Any idea why this would be?

- I have all the editing privileges set to edit/update/delete etc.

0 Kudos
MehdiPira1
Esri Contributor

Hi Connor Vincent‌,

You probably need to refresh the feature layer url or the url of the web map that contains this feature layer in the web browser. Or at least close and open the feature layer attribute table in the web map to see the changes after running the script.

My apologies I also missed this; update lines 20 and 25 to include index as follows:

fset.features[index].attributes['roomstatus'] = 'Vacant'


fset.features[index].attributes['roomstatus'] = 'Occupied'‍‍‍‍‍‍‍‍
Server
by
New Contributor II

Hi Mehdi,

I'm still not seeing changes in the data on ArcOnline unfortunately. 

from arcgis.gis import GIS
gis = GIS(url='xxxxxxxxxxxxx', username='xxxxxxxxxxx', password='xxxxxxxxx')

import datetime
from arcgis.features import FeatureSet, Feature

itemId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
fs=gis.content.get(itemId)

#search for the feature layer/service
featureLayer_item = gis.content.search('type:"Feature Service" AND title:"xxxxxxxxxxxxxxxxxxxx"')

#access the item's feature layers
feature_layers = featureLayer_item[0].layers
flayer = feature_layers[0]
#query all the features and get the spatial dataframe
fset = feature_layers[0].query()
flayer_rows = fset.sdf

for index, row in flayer_rows.iterrows():
    today = datetime.datetime.today()
    if row['FromDate'] <= today <= row['ToDate']:
        print("Updating feature layer ....")
        print(row['FromDate'])
        print(today)
        print(row['ToDate'])
        fset.features[index].attributes['Room_Status'] = 'Occupied'
        #fset.features[0].attributes['Total'] = '1'
        flayer.edit_features(updates = fset.features)
        print("Feature layer is set to Occupied!")

        
    else:
        print("Updating feature layer ....")
        fset.features[index].attributes['Room_Status'] = 'Vacant'
        #fset.features[0].attributes['Total'] = '0'
        flayer.edit_features(updates = fset.features)
        print("Feature layer is set to Vacant!")
        

print("Complete")
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

It reads the dates correctly, and states the correct print out for each row:

But then when looking at the data, The "Data Last updated" in the top right corner is correct (every time the script is run this is updated). Despite this, the Room_Status field is still the same as before the script is run (ie does not reflect the fromDate - ToDate field).

Its like its able to read the data, but is not actually able to edit. 

0 Kudos
MehdiPira1
Esri Contributor

Connor Vincent‌,

1. Is the Room_Status a coded-value domain field? if yes, you need to use the codes/numbers instead of strings.

2. Some of the date columns are null. This might confuses the current script as null is not handled in this script. you can exclude the null rows in dates and do another test.

3. I can see that you also have included the [index] in the second to last line. Just remove [index].

4. Test the script on other fields, simply change the filed name from Room_Status to another. You also need to see if that field has a domain.

MehdiPira1
Esri Contributor