searchcursor only takes first value in field

4133
8
Jump to solution
04-30-2015 02:30 AM
MarkWisniewski
New Contributor III

My script ArcGIS 10.2 is using the searchcursor to read the mLanduse feature class to return the value in lField, but it is only returning the first value in lField to populate the sField in mSoils. Is my cursor2.updateRow in the wrong spot?

# Create a cursor on a feature class
with arcpy.da.SearchCursor(mLanduse, lField) as cursor:

# Loop through the rows and update the blank sField values in mSoils with the lField values from mLanduse
     for row in cursor:
         with arcpy.da.UpdateCursor(mSoils, sField) as cursor2:
             for row2 in cursor2:
                 if row2[0] == ' ':
                     row2[0] = row[0]
                 else:
                     row2[0] = ' '
                 cursor2.updateRow(row2)
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
curtvprice
MVP Esteemed Contributor

You really do need to do the spatial join, of course you can make it more efficient by doing a Select Layer By Location before you do your overlay (as Mr. Bixby suggests).

View solution in original post

8 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Ernst,

I believe your workflow may be incorrect.  Your above code will find the first lField value in the mLanduse feature class, then update every row in the mSoils feature class where the sField is blank.  It will then find the second row in mLanduse and update every row in mSoils where the SField is blank.  It will continue to do this.

Is there a related field in mLanduse and mSoils where you can perform a join, select the blank rows, and then use the field calculator to update these rows?

If possible, would you be able to provide a small sample of you data?

MarkWisniewski
New Contributor III

Jake, thanks for explaining this. There is no related table. My output is doing the following as stated by yourself;

"Your above code will find the first lField value in the mLanduse feature class, then update every row in the mSoils feature class where the sField is blank".

Okay, how do I change my script so it finds the first lField value in the mLanduse feature class then updates ONLY the rows according to the SelectByLocation in the mSoils feature class where the sField is Blank?

And then; "It will then find the second row in mLanduse and update every row in mSoils where the SField is blank".

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Attached is some data you can test with.  The below script will update the 'Soil' field in the 'Soil' feature class based on the 'SoilType' field within the 'LandUse' feature class.  The code performs a spatial join, joins the output from this tool to the Soil feature class, selects all empty values in the Soil field and then updates these values using the Calculate Field tool.

import arcpy
from arcpy import env
env.overwriteOutput = 1
env.workspace = r"C:\temp\python\test.gdb"

mLanduse = "LandUse"
mSoils = "Soil"

arcpy.SpatialJoin_analysis(mSoils, mLanduse, r"IN_MEMORY\join")

arcpy.MakeFeatureLayer_management(mSoils, "soilsLyr")
arcpy.MakeFeatureLayer_management(r"IN_MEMORY\join", "joinLyr")

arcpy.AddJoin_management("soilsLyr", "OBJECTID", "joinLyr", "TARGET_FID")
arcpy.SelectLayerByAttribute_management("soilsLyr", "NEW_SELECTION", "Soil.Soil = ''")

arcpy.CalculateField_management("soilsLyr", "Soil.Soil", "[join.SoilType]", "VB")
print 'finished'
JoshuaBixby
MVP Esteemed Contributor

If I understand correctly what you are trying to do, and using as much of your original code as possible, I roughed out the following:

with arcpy.da.SearchCursor(mLanduse, ["SHAPE@", lField]) as cursor:
    for row in cursor:
        arcpy.SelectLayerByLocation_management(
            mSoils_Layer, "WITHIN", row[0]
        )
        with arcpy.da.UpdateCursor(mSoils_Layer, sField) as cursor2:
            for row2 in cursors2:
                if row2[0] == '':
                    row2[0] = row[1]
                cursor2.updateRow(row2)

If this works, I can explain how your original code had some parts out of order.

0 Kudos
MarkWisniewski
New Contributor III

Joshua,

Thanks for your effort, but no luck. The script doesn't like the SelectByLocation in the SearchCursor.

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Curios, what is the specific error message?  (By the way, it is a good practice to include specific error messages instead of general comments like "doesn't like.").  It could be I just gave some incorrect syntax or names since I was interpreting your original code snippet.

0 Kudos
MarkWisniewski
New Contributor III

Joshua,

I'm not really sure to be honest. I do not do the printing side of things in IDLE (bad practice?). I have the script open in ArcGIS, run it, if it works great, if not, I do more research and ask questions online and update script through IDLE and repeat process.

Now I'm trying to work out why my loop isn't stopping.

0 Kudos
curtvprice
MVP Esteemed Contributor

You really do need to do the spatial join, of course you can make it more efficient by doing a Select Layer By Location before you do your overlay (as Mr. Bixby suggests).