Using field values to update a field using a search and update cursor

1605
4
04-12-2017 12:46 PM
TessOldemeyer
Occasional Contributor

I am trying to update a field using the arcpy.da.Update cursor where I can use two field values from a select by location result to populate a new field. It seems like a spatial join route may be the best approach here. With this code, I am now receiving an error of 'tuple' object has no attribute 'GEN_UNITS' for the 'result = joinsubrow.GEN_UNITS/joinsubrow.LINES' line. Do I need to search out these field values separately in separate search cursors? What would be the best route here? Thanks in advance!

   import arcpy    
   from arcpy import env     
   arcpy.env.OverwriteOutput = True    
   defaultGdbPath = 'C:\Topo_Check_Tess_V5.gdb'    
   subLayer='C:\Topo_Check_Tess_V5.gdb\Subs'   
   transLayer='C:\Topo_Check_Tess_V5.gdb\TLines'  
   ppLayer='C:\Topo_Check_Tess_V5.gdb\PPs'        
   arcpy.AddField_management(subLayer, "GU_Count", "SHORT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")   
   GUCountField = "GU_Count"
      
   #Make feature layer   
   arcpy.MakeFeatureLayer_management(ppLayer, "ppLayerGU")    

   #Make feature layer   
   arcpy.MakeFeatureLayer_management(transLayer, "transLayerGU")    

   pp_trans_GUJoin ='C:\Topo_Check_Tess_V5.gdb\pp_trans_GU_SpatialJoin'    
   SubLayer_pp_trans_GUJoin ='C:\Topo_Check_Tess_V5.gdb\SubLayer_pp_trans_GUSpatialJoin'    

   #spatial join of feature layers   
   arcpy.SpatialJoin_analysis ("transLayerGU", "ppLayerGU", pp_trans_GUJoin,'JOIN_ONE_TO_ONE', 'KEEP_ALL', '#', 'WITHIN_A_DISTANCE', .000002)      

   #Make feature layer   
   arcpy.MakeFeatureLayer_management(subLayer, "SubLayer_Layer")    

   #spatial join of feature layers   
   arcpy.SpatialJoin_analysis ("SubLayer_Layer", "ppLayerGU", SubLayer_pp_trans_GUJoin, 'JOIN_ONE_TO_ONE', 'KEEP_ALL', '#','WITHIN_A_DISTANCE', .000002)
   
   #Make feature layer   
   arcpy.MakeFeatureLayer_management(SubLayer_pp_trans_GUJoin, "JoinLayer")    

   LINE_Fields = ['LINES','GEN_UNITS']     

   with arcpy.da.UpdateCursor (subLayer, [GUCountField, "SHAPE@"]) as GUCalcCursor:       
      for subrow in GUCalcCursor:           
         arcpy.SelectLayerByLocation_management("JoinLayer",'WITHIN_A_DISTANCE', subrow[1], .000002, "NEW_SELECTION")              
         with arcpy.da.SearchCursor("JoinLayer", LINE_Fields) as JoinLayerCursor:               
            for joinsubrow in JoinLayerCursor:                    
            result = joinsubrow.GEN_UNITS/joinsubrow.LINES          
      subrow[0] = result         
      GUCountField.updateRow(subrow)
0 Kudos
4 Replies
JoshuaBixby
MVP Esteemed Contributor

You are mixing the syntax for working with the older/original cursors and the newer Data Access cursors.  The following line isn't valid:

result = joinsubrow.GEN_UNITS/joinsubrow.LINES

The DA search cursor returns a tuple containing values for the fields specified in the cursor, not a row object like the original search cursor.

What happens when you change the line to:

result = joinsubrow[1] / joinsubrow[0]
0 Kudos
TessOldemeyer
Occasional Contributor

Thanks! That was definitely a huge part of the problem. I have attached the newest rendition. It is still probably full of quirks, but seems to be getting somewhere. It is currently getting stuck on line 66 with an AttributeError: 'str' object has no attribute 'updateRow'. 

import arcpy
from arcpy import env

arcpy.env.OverwriteOutput = True

defaultGdbPath = 'C:\Topo_Check_Tess_V5.gdb'

subLayer='C:\Topo_Check_Tess_V5.gdb\Subs'
transLayer='C:\Topo_Check_Tess_V5.gdb\TLines'
ppLayer='C:\Topo_Check_Tess_V5.gdb\PP'


arcpy.AddField_management(subLayer, "GU_Count", "SHORT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
GUCountField = "GU_Count"



#Make feature layer
arcpy.MakeFeatureLayer_management(ppLayer, "ppLayerGU")

#Make feature layer
arcpy.MakeFeatureLayer_management(transLayer, "transLayerGU")

pp_trans_GUJoin ='C:\Topo_Check_Tess_V5.gdb\pp_trans_GU_SpatialJoin'
SubLayer_pp_trans_GUJoin = 'C:\Topo_Check_Tess_V5.gdb\SubLayer_pp_trans_GUSpatialJoin'

#spatial join of feature layers
arcpy.SpatialJoin_analysis ("transLayerGU", "ppLayerGU", pp_trans_GUJoin, 'JOIN_ONE_TO_ONE', 'KEEP_ALL', '#', 'WITHIN_A_DISTANCE', .000002) 

#Make feature layer
arcpy.MakeFeatureLayer_management(subLayer, "SubLayer_Layer")

#spatial join of feature layers
arcpy.SpatialJoin_analysis ("SubLayer_Layer", "ppLayerGU", SubLayer_pp_trans_GUJoin, 'JOIN_ONE_TO_ONE', 'KEEP_ALL', '#', 'WITHIN_A_DISTANCE', .000002) 


#Make feature layer
arcpy.MakeFeatureLayer_management(SubLayer_pp_trans_GUJoin, "JoinLayer")


with arcpy.da.UpdateCursor (subLayer, [GUCountField, "SHAPE@"]) as GUCalcCursor:
    for subrow in GUCalcCursor:
        arcpy.SelectLayerByLocation_management("JoinLayer", 'WITHIN_A_DISTANCE', subrow[1], .000002, "NEW_SELECTION") 
        if int(arcpy.GetCount_management(in_rows="JoinLayer").getOutput(0))==1:       
            with arcpy.da.SearchCursor("JoinLayer",['LINES','GEN_UNITS']) as JoinLayerCursor:
        
                for joinsubrow in JoinLayerCursor:
                    
                        GEN_UNITS = joinsubrow[1]
                    
                   
                        LINES = joinsubrow[0]
                   
                print GEN_UNITS
                print LINES

                
                if joinsubrow[1] > 0:
                    result = GEN_UNITS/LINES 
                else:
                    result = 0
                print result
                
                subrow[0] = result
        
                GUCountField.updateRow(subrow)
0 Kudos
DarrenWiens2
MVP Honored Contributor

Also, once you get to it, the final line should be:

GUCalcCursor.updateRow(subrow)
0 Kudos
TessOldemeyer
Occasional Contributor

Thanks! Just saw this! Looks like that worked.

0 Kudos