error with UpdateCursor in Jupyter notebook

238
16
03-18-2021 05:24 AM
GrantBenn1
New Contributor III

Hi,

I am new to Jupyter notebooks in AGOL. I am trying to develop a script which updates a field in  a hosted feature layer based on what has been entered in other fields. I am getting an error (code 400) pointing to the "for row in cursor:" line. This script works perfectly on my desktop machine. Any ideas as to what might be wrong? Here is what I am seeing in Notebook.

GrantBenn1_0-1616070232033.png

Thanks,

Grant

 

0 Kudos
16 Replies
jcarlson
MVP Regular Contributor

For one thing, ArcPy is only available in the advanced notebooks (the ones that cost you credits to run), so I'd make sure your notebook runtime is correct.

If you're working with hosted layers and AGOL, you're much better off using the ArcGIS Python API and spatially enabled dataframes. Here's a sample of how you might use it:

 

from arcgis import GIS

# Log in to portal; for AGOL notebooks, you can also use gis = GIS("home")
gis = GIS('portal-url', 'user', 'password')

# Get your hosted layer you want updated
fc = gis.content.get('itemID').layers[0]

# Query out all features to a dataframe
df = fc.query(out_fields=['the', 'fields', 'you', 'need'], return_geometry=False, as_df=True)

# Subset rows for those where 'field_a', etc., is greater than 0, add 1 to 'target_field'
df.loc[df['field_a'] > 0, 'target_field'] = df['target_field'] + 1
df.loc[df['field_b'] > 0, 'target_field'] = df['target_field'] + 1

# And so on

# Submit updated dataframe back to hosted layer as updates
fc.edit_features(updates=df.spatial.to_featureset())

 

 

It's quite different from using cursors, but once you get the hang of using dataframes (see the pandas docs for more info), it will become much, much easier. And more versatile, as pandas is widely used with other python modules, and can import/export a wide variety of file formats.

Rather than using a bunch of if statements, the pandas loc indexer is grabbing a selection of rows and columns from the dataframe and operating on them separately. Within loc[x, y], x represents the rows. Here we supply "df['field_a'] > 0", so we're getting back all the rows that meet the condition. y represents the columns, and specifying a single column by its label, 'target_field', gives us only those values we wish to update.

Setting that selection equal to the 'target_field' value + 1, the dataframe only grabs the value at the same index, so you don't have to specify a subset for that operation.

- Josh Carlson
Kendall County GIS
0 Kudos
GrantBenn1
New Contributor III

Hi Josh,

Thanks for the interesting response.

I am indeed using an advanced notebook.

I will take a look at the dataframes, but would also really like to solve the problem with the UpdateCursor.

Thanks again,

Grant

0 Kudos
DanPatterson
MVP Notable Contributor

arcpy and arcpy.da are imported somewhere else in the notebook?

the error stems from the input featureclass name or location or the specified fields.

check both to make sure they "exist" in your code


... sort of retired...
0 Kudos
GrantBenn1
New Contributor III

Hi Dan,

Thanks a lot. Yes arcpy and arcpy.da are imported at the top of the notebook.

I found a small error in the fields list which I think was breaking it, so the error is now gone. However, now it doesn't seem to be resolving any of the if statements,. In fact it doesn't even appear to be stepping into the UpdateCursor. I tested this by putting a print statement directly after "for row in cursor:'. It runs with no error but isn't doing anyone of the assessments and incrementing the counter.

Thanks,

Grant

0 Kudos
DanPatterson
MVP Notable Contributor

UpdateCursor—ArcGIS Pro | Documentation

that row (row[14]???? will only get updated in the last if statement

print the value prior to updating the row, I can't tell what is going on because flipping back and forth to the image is difficult.  Try code formatting to make it easier to view code samples

Code formatting ... the Community Version - Esri Community


... sort of retired...
0 Kudos
GrantBenn1
New Contributor III

Hi Dan,

 

Sorry about the problems with image of the code.

Here is the code:

from arcgis.gis import GIS
gis = GIS("home")
import arcpy, arcpy.da, requests, json

inputFC = ''https://services8.arcgis.com/eDOP1zOdWfMRGgMh/arcgis/rest/services/?????/FeatureServer/0''
TableFields_VehicleAvailability = ['MajorPumpActualNum','MediumPumpActualNum','FireEnginesActualNum','WaterTankersActualNum','UrbanPumpersActualNum','FoamTendersActualNum','VeldFireVehActualNum','AerialFireActualNum','CommUnitsActualNum','RapidUnitsActualNum','FuelTendersActualNum','CrewBusesActualNum','FireBoatsActualNum','VehReplacePolicy','VehAvailMainScore']#,'VehAvailBonusScore','VehAvailCombScore']

VehAvailMain_Score = 0
VehAvailBonus_Score = 0

#calculate classification score for Vehicle Availability
with arcpy.da.UpdateCursor(inputFC, TableFields_VehicleAvailability) as cursor:
    for row in cursor:
        VehAvailMain_Score = 0
        VehAvailBonus_Score = 0
        if (row[0] > 0 or row[1] > 0): #Major and Medium Pumps
            VehAvailMain_Score = VehAvailMain_Score + 1
            print(row[1])
        if row[2] > 0: #Fire Engines
            VehAvailMain_Score = VehAvailMain_Score + 1
        if row[3] > 0: #Water Tankers
            VehAvailMain_Score = VehAvailMain_Score + 1
        if row[6] > 0: #Veld Fire Vehicles
            VehAvailMain_Score = VehAvailMain_Score + 1
        if (row[13] == 'Yes' or row[13] == 'No'): #vehicle replacement policy because always either Yes or No
            row[14] = VehAvailMain_Score #VehAvailMainScore
        print(VehAvailMain_Score)
        cursor.updateRow(row)
del cursor

 

 

0 Kudos
DanPatterson
MVP Notable Contributor
'' .... ''

two single quotes surround your inputFC path.  You said you found some issue with your field names.  Are you still getting the same error message?

also all those

VehAvailMain_Score = VehAvailMain_Score + 1 #---- current
VehAvailMain_Score += 1  # ---- suggested

 lines can be written as suggested 

and

    for row in cursor:
        VehAvailMain_Score = 0  # ---- redundant
        VehAvailBonus_Score = 0 # ---- redundant

are defined outside the with statement and again within it.  Do you want it redefined there as well?


... sort of retired...
0 Kudos
GrantBenn1
New Contributor III

Hi Dan,

two single quotes - sorry that is an error that crept in when I copied the code into the reply.  The actual code I am testing has the inputFC in one set of single quotes.

I sorted out the issue with the field names and am no longer getting the error message, but the problem now is that the code doesn't seem to be getting into the UpdateCursor. None of the operations within the UpdateCursor are being fired. I placed some print statements within the UpdateCursor to test this and none of them print.

 

0 Kudos
DanPatterson
MVP Notable Contributor

If it isn't getting to the cursor, then print statement outside are needed.

You indicate that it is supposed to be a featureclass.  If so, then you should be able to print some of its properties.  If that fails, then it isn't a featureclass, it doesn't exist or something else.

See  FeatureClass properties—ArcGIS Pro | Documentation


... sort of retired...
0 Kudos