Search code examples
pythonesriarcpy

Arcpy fails to field calculate integer source value to LONG field


I am working on a script that iterates through the records of "feature class A", performs a spatial selection (flow tracing) with each individual "A" record on "feature class B" and then field calculates an attribute from "A" into the resulting selected records in "B"

Basically for each downstream-most node on a sewer pipe network, trace upstream and assign the ID of that downstream node to all upstream features.

The attribute value will always be a whole number, but sometimes field in A is formatted as text and sometimes as a number.

I can successfully perform this calulation if:

A is formatted as TEXT

and

B is formatted as LONG

the operation fails to calculate anything if:

A is formatted as LONG

and

B is Formatted as LONG

What am I missing so that this will work for both potential input cases if the ID for A is either text whole number or an integer whole number format?

...
for row in cursor:
ID = (str(row.getValue(str(flagname))))
whereclause = ((str(flagname)) +str(' = ') + "'%s'" %ID)
fc=str(r"outfalls_lyr")
arcpy.MakeFeatureLayer_management(traceflag, fc)

try:
    arcpy.SelectLayerByAttribute_management(fc, "NEW_SELECTION",str(whereclause))
    arcpy.MakeFeatureLayer_management( fc,r"in_memory\temp_of")
    arcpy.TraceGeometricNetwork_management(geomnet, r"in_memory\outNet",r"in_memory\temp_of" , "TRACE_UPSTREAM", "", "", "","", "", "NO_TRACE_ENDS", "NO_TRACE_INDETERMINATE_FLOW", "", "", "AS_IS", "", "", "", "AS_IS")
    for layer in arcpy.mapping.Layer(r"in_memory\outNet"):
        try:
            print arcpy.mapping.ListLayers(layer)
            calc = str('"%s"' %ID)
            arcpy.CalculateField_management (layer, fieldname, calc,"","")
        except:
            print arcpy.GetMessages()

except:
    print arcpy.GetMessages()

Cross-posted to GIS Stack Exchange, too.


Solution

  • The problem appears to have been in how the selection query was parsed and executed. For one of the field types, it returned a an empty selection, so there were no trace flags generated from which to perform the upstream trace selection. this returned an empty trace result so there were no record into which to calculate the ID.

    adding a test for the source field type appears to have solved the problem.

    I am positive that there are more efficient and cleaner way to write this, but the updated code below DOES appear to perform the desired results in both cases ( source field is TEXT or source field is LONG) so it's an adequate fix for my purposes.

    cursor = arcpy.SearchCursor(traceflag)
    
    fields = arcpy.ListFields(traceflag)
    for field in fields:
        if field.name == flagname and field.type == 'String':
            typeIsString = "True"
        elif field.name == flagname and not field.type == 'String':
            typeIsString = "False"
    
    
    for row in cursor:
        if typeIsString == "True":
            ID = str((row.getValue(str(flagname))))
        elif typeIsString == "False":
            ID = int((row.getValue(str((flagname)))))
    whereclause = (flagname + ' = ' + `ID`)
    fc=str(r"outfalls_lyr")
    arcpy.MakeFeatureLayer_management(traceflag, fc)
    
    try:
        arcpy.SelectLayerByAttribute_management(fc, "NEW_SELECTION",str(whereclause))
        arcpy.MakeFeatureLayer_management( fc,r"in_memory\temp_of")
        arcpy.TraceGeometricNetwork_management(geomnet, r"in_memory\outNet",r"in_memory\temp_of" , "TRACE_UPSTREAM", "", "", "","", "", "NO_TRACE_ENDS", "NO_TRACE_INDETERMINATE_FLOW", "", "", "AS_IS", "", "", "", "AS_IS")
        for layer in arcpy.mapping.Layer(r"in_memory\outNet"):
            try:
                print arcpy.mapping.ListLayers(layer)
                calc = str('"%s"' %ID)
                arcpy.CalculateField_management(layer, fieldname, ID, "PYTHON", "")
            except:
                print arcpy.GetMessages()