Select to view content in your preferred language

Getting Error in my where clause using cursor in arcpy.

8230
46
Jump to solution
08-08-2021 01:55 AM
broy06
by
New Contributor III

I'm currently using Arcmap 10.7 version. I'm guessing my error is in the where clause. Could anyone please help me to get rid from this problem?. I'm not able to print the cursor part i.e., 

Print (MEASUREDLENGTH_Risk_Score) # Not getting the value of MEASUREDLENGTH

 

Below is my code-:

 

import arcpy
arcpy.env.workspace = "D:\pipe\map.gdb"
featureClass_1 = "P_Pipes"
Table_Pipe = "Pipe_Risk"
fieldNames_1 = [ "Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE", "Risk_Score"]
fieldNames_Pipe = ["Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTHLOWERLIMIT" ,"MEASUREDLENGTHUPPERLIMIT" , "INSTALLATIONDATELOWERLIMIT" , "INSTALLATIONDATEUPPERLIMIT" , "OVERALLRISKSCORE"]


def Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH,  INSTALLATIONDATE):

    ML_Out_fields = ["MEASUREDLENGTHLOWERLIMIT" ,"MEASUREDLENGTHUPPERLIMIT" , "OVERALLRISKSCORE"]
    ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= " + MEASUREDLENGTH + " and MEASUREDLENGTHUPPERLIMIT >= " + MEASUREDLENGTH 
    print(ML_where_Clause)
    
    Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ML_Out_fields, ML_where_Clause)
    for row in Table_Pipe_Cursor:
        lst.append(row[2])
        MEASUREDLENGTH_Risk_Score = row[2]
        print ((MEASUREDLENGTH_Risk_Score))

Pipe_Risk_Score("Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" ,  "INSTALLATIONDATE")

 

 

0 Kudos
46 Replies
by Anonymous User
Not applicable

You are not assigning a value to the variable named INSTALLATIONDATE before you try to pass it into the function.  Using "" is falsely working because you are simply passing strings "OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE"-  but that is not passing the data (floats, dates) that you think it is.

Assign a value to the variable INSTALLATIONDATE first, before passing it to the function as the parameter such as:

 

INSTALLATIONDATE = datetime.strptime('2012-02-10', '%Y-%m-%d')

Pipe_Risk_Score("Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" , INSTALLATIONDATE)

 

You will not get the Name Error. You need to do this for each parameter in your function call if you don't want the string, or else you will get the same false positive, which will not work in any sql query within the function since it is not the data (floats, dates).

0 Kudos
broy06
by
New Contributor III

Hi sir, As you have defined or initialize value for a variable like 

OPERATINGPRESSURE = 36
MEASUREDLENGTH = 12

INSTALLATIONDATE = datetime.strptime('08/03/2021 12:43:34')

Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH,  INSTALLATIONDATE)

 

So, how should I define my values for the variable in a function call, since each variable has so many different values from the table? How to fetch the data for each variable from a lookup table. Please have a look at the table given below-:   Thank you!

0 Kudos
by Anonymous User
Not applicable

Use a search cursor to iterate over the table.

Material = 'Something'
with arcpy.da.SearchCursor(yourtable, ["OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE"]) as sCur:
    for row in sCur:
         OPERATINGPRESSURE = row[0]
         MEASUREDLENGTH = row[1]
         INSTALLATIONDATE = row[2]
         Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH, INSTALLATIONDATE)
         # or 
         # Pipe_Risk_Score(Material, row[0], row[1], row[2])
 
0 Kudos
broy06
by
New Contributor III

Sir, Actually i want the average of all these function at last in a return. Please have a look at my full code. I'm interested in accessing the "overallrisk" score of the value of all these parameters like Material, OPERATINGPRESSURE and so on.

import arcpy
arcpy.env.workspace = "D:\pipe\map.gdb"
featureClass_1 = "P_Pipes"
Table_Pipe = "Pipe_Risk"
fieldNames_1 = [ "Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE", "Risk_Score"]
fieldNames_Pipe = ["Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTHLOWERLIMIT" ,"MEASUREDLENGTHUPPERLIMIT" , "INSTALLATIONDATELOWERLIMIT" , "INSTALLATIONDATEUPPERLIMIT" , "OVERALLRISKSCORE"]


def Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH,  INSTALLATIONDATE):

# Case: Material

#Material_Out_fields = ["Material" , "OVERALLRISKSCORE"]

Material_where_Clause = "Material = " + Material
Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ["Material" , "OVERALLRISKSCORE"],Material_where_Clause)
for row in Table_Pipe_Cursor:
# lst.append(row[1])
Material_Risk_Score = row[1]
print Material_Risk_Score

# Case: Operating Pressure

OP_Out_fields = ["OPERATINGPRESSURE" , "OVERALLRISKSCORE"]
OP_where_Clause = "OPERATINGPRESSURE = " + OPERATINGPRESSURE
Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, OP_Out_fields, OP_where_Clause)

for row in Table_Pipe_Cursor:
lst.append(row[1])
OPERATINGPRESSURE_Risk_Score = row[1]
print (OPERATINGPRESSURE_Risk_Score)


# Case: ML

ML_Out_fields = ["MEASUREDLENGTHLOWERLIMIT" ,"MEASUREDLENGTHUPPERLIMIT" , "OVERALLRISKSCORE"]
ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= " + MEASUREDLENGTH + " and MEASUREDLENGTHUPPERLIMIT >= " + MEASUREDLENGTH #.format(MEASUREDLENGTH)
print ML_where_Clause
#Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ML_Out_fields, ML_where_Clause)
#ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= " + MEASUREDLENGTH + " and MEASUREDLENGTHUPPERLIMIT >= " + MEASUREDLENGTH.format(MEASUREDLENGTH, MEASUREDLENGTH)
# print(ML_where_Clause)
#ML_where_Clause = "CAST(MEASUREDLENGTHUPPERLIMIT AS INTEGER <= "MEASUREDLENGTHUPPERLIMIT" and "MEASUREDLENGTHUPPERLIMIT" >= "MEASUREDLENGTHLOWERLIMITTable_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ML_Out_fields, ML_where_Clause)

"""for row in Table_Pipe_Cursor:
lst.append(row[2])
MEASUREDLENGTH_Risk_Score = row[2]
print MEASUREDLENGTH_Risk_Score"""


# Case: ID

#INSTALLATIONDATE = datetime.strptime("01/01/1935 00:00:00" , "01/01/2035 00:00:00")
#ID_Out_fields = ["INSTALLATIONDATELOWERLIMIT" , "INSTALLATIONDATEUPPERLIMIT" , "OVERALLRISKSCORE"]
#ID_where_Clause = "INSTALLATIONDATELOWERLIMIT <= datetime(01/01/1935 00:00:00) and INSTALLATIONDATEUPPERLIMIT >= datetime(01/01/2035 00:00:00)"
#ID_where_Clause = "(INSTALLATIONDATELOWERLIMIT <= {} and INSTALLATIONDATEUPPERLIMIT >= {})".format(INSTALLATIONDATE)
#Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ID_Out_fields, ID_where_Clause)
#for row in Table_Pipe_Cursor:
#lst.append(row[2])
#ID_Risk_Score = row[2]
#print (ID_Risk_Score)"""


#Final_Risk_Score = (Material_Risk_Score + OP_Risk_Score + ML_Risk_Score + ID_Risk_Score)/4

 



#Pipe_Risk_Score(Material , OPERATINGPRESSURE , MEASUREDLENGTH , INSTALLATIONDATE) # Showing me Name error using this line without quotes
Pipe_Risk_Score("Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE")

 

0 Kudos
broy06
by
New Contributor III

But I'm interested in a overall risk score of individual value. I want the average as a return function.

 

Please have a look at my complete code:

import arcpy
from datetime import datetime
arcpy.env.workspace = "D:\Pipe\map.gdb"
featureClass_1 = "P_Pipes"
Table_Pipe = "Pipe_Risk"
fieldNames_1 = [ "Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE", "Risk_Score"]
fieldNames = ["Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTHLOWERLIMIT" ,"MEASUREDLENGTHUPPERLIMIT" , "INSTALLATIONDATELOWERLIMIT" , "INSTALLATIONDATEUPPERLIMIT" , "OVERALLRISKSCORE"]

lst=[]

def Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH, INSTALLATIONDATE):


# Case: Material

#Material_Out_fields = ["Material" , "OVERALLRISKSCORE"]

Material_where_Clause = "Material = " + Material
Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ["Material" , "OVERALLRISKSCORE"],Material_where_Clause)
for row in Table_Pipe_Cursor:
# lst.append(row[1])
Material_Risk_Score = row[1]
print Material_Risk_Score

# Case: Operating Pressure

OP_Out_fields = ["OPERATINGPRESSURE" , "OVERALLRISKSCORE"]
OP_where_Clause = "OPERATINGPRESSURE = " + OPERATINGPRESSURE
Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, OP_Out_fields, OP_where_Clause)

for row in Table_Pipe_Cursor:
lst.append(row[1])
OPERATINGPRESSURE_Risk_Score = row[1]
print (OPERATINGPRESSURE_Risk_Score)


# Case: ML

ML_Out_fields = ["MEASUREDLENGTHLOWERLIMIT" ,"MEASUREDLENGTHUPPERLIMIT" , "OVERALLRISKSCORE"]
ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= " + MEASUREDLENGTH + " and MEASUREDLENGTHUPPERLIMIT >= " + MEASUREDLENGTH #.format(MEASUREDLENGTH)
print ML_where_Clause
#Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ML_Out_fields, ML_where_Clause)
#ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= " + MEASUREDLENGTH + " and MEASUREDLENGTHUPPERLIMIT >= " + MEASUREDLENGTH.format(MEASUREDLENGTH, MEASUREDLENGTH)
# print(ML_where_Clause)
#ML_where_Clause = "CAST(MEASUREDLENGTHUPPERLIMIT AS INTEGER <= "MEASUREDLENGTHUPPERLIMIT" and "MEASUREDLENGTHUPPERLIMIT" >= "MEASUREDLENGTHLOWERLIMITTable_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ML_Out_fields, ML_where_Clause)

"""for row in Table_Pipe_Cursor:
lst.append(row[2])
MEASUREDLENGTH_Risk_Score = row[2]
print MEASUREDLENGTH_Risk_Score"""


# Case: ID

INSTALLATIONDATE = datetime.strptime("1935-01-01 " ,"%Y-%m-%d") #"01/01/2035 00:00:00")
ID_Out_fields = ["INSTALLATIONDATELOWERLIMIT" , "INSTALLATIONDATEUPPERLIMIT" , "OVERALLRISKSCORE"]
ID_where_Clause = "INSTALLATIONDATELOWERLIMIT <= datetime(1935-01-01 ) and INSTALLATIONDATEUPPERLIMIT >= datetime(2035-01-01 )"
#ID_where_Clause = "(INSTALLATIONDATELOWERLIMIT <= {} and INSTALLATIONDATEUPPERLIMIT >= {})".format(INSTALLATIONDATE)
Table_Pipe_Cursor = arcpy.da.SearchCursor(Table_Pipe, ID_Out_fields, ID_where_Clause)
for row in Table_Pipe_Cursor:
#lst.append(row[2])
ID_Risk_Score = row[2]
print (ID_Risk_Score)


#Final_Risk_Score = (Material_Risk_Score + OP_Risk_Score + ML_Risk_Score + ID_Risk_Score)/4

#Pipe_Risk_Score(Material , OPERATINGPRESSURE , MEASUREDLENGTH , INSTALLATIONDATE) # Showing me Name error using this line without quotes
Pipe_Risk_Score("Material" , "OPERATINGPRESSURE" , "MEASUREDLENGTH" , "INSTALLATIONDATE")

0 Kudos
by Anonymous User
Not applicable

This is getting beyond the scope of the original question.  If the field values you are tying to use in the queries are coming from the same table as what you are using to get the information from, I think you could simplify this script into a single cursor and drop the multiple sql queries on each field. 

I am unclear if you are trying to average each features value across the fields, or average the field across all features.  This is not tested but should do both and get you started- you can add/ delete what you need when you debug it against the data.

 

import arcpy

arcpy.env.workspace = "D:\Pipe\map.gdb"
featureClass_1 = "P_Pipes"
Table_Pipe = "Pipe_Risk"

# Lists for holding values from the cursor
material_overall = []
opPressureOverall = []
measuredlengthOverall = []
riskscoreOverall = []

with arcpy.da.SearchCursor(Table_Pipe, ["Material", "OPERATINGPRESSURE", "MEASUREDLENGTH",
                                        "INSTALLATIONDATELOWERLIMIT", "INSTALLATIONDATEUPPERLIMIT",
                                        "OVERALLRISKSCORE"]) as sCur:
    for row in sCur:
        Material_Risk_Score = row[0]
        # filter Nulls
        if Material_Risk_Score is not None:
            material_overall.append(Material_Risk_Score)

        OPERATINGPRESSURE_Risk_Score = row[1]
        if OPERATINGPRESSURE_Risk_Score is not None:
            measuredlengthOverall.append(OPERATINGPRESSURE_Risk_Score)

        MEASUREDLENGTH_Risk_Score = row[2]
        if MEASUREDLENGTH_Risk_Score is not None:
            measuredlengthOverall.append(MEASUREDLENGTH_Risk_Score)
        
        # This can probably be just a Null check instead of dates becuase this will always be true for the values shown in the table unless its Null.
        # if row[3] <= '2035-01-01' and row[4] >= '1935-01-01':
        if row[3] is not None and row[4] is not None:
            ID_Risk_Score = row[5]
            riskscoreOverall.append(ID_Risk_Score)
            # There are no values in the other fields if the dates are filled in so not sure if this is correct:
            print "Feature risk average: {}".format(
                Material_Risk_Score + OPERATINGPRESSURE_Risk_Score + MEASUREDLENGTH_Risk_Score + ID_Risk_Score / 4)

        else:
            # average the three fields for each feature leaving the installation out because there are no date values if these
            # fields have values.
            print "Feature risk average: {}".format(
                Material_Risk_Score + OPERATINGPRESSURE_Risk_Score + MEASUREDLENGTH_Risk_Score / 3)


# if you want average of the fields across all features.
print 'material_overall average = {}'.format(sum(material_overall) / len(material_overall))
print 'Operating Pressure average = {}'.format(sum(measuredlengthOverall) / len(measuredlengthOverall))
print 'Measured Length average = {}'.format(sum(measuredlengthOverall) / len(measuredlengthOverall))
print 'Risk Score average = {}'.format(sum(riskscoreOverall) / len(riskscoreOverall))

 

 

0 Kudos
broy06
by
New Contributor III

Sir, What i have to actually do is taking the "overall risk score" from the lookup table for each value in the feature class and then after accessing the "Overall risk score" for each value in my lookup table. I'm trying to update it in the main feature class( I have added a new field "Risk_Score" here)

 

So, what i wanna do is reading the value from the lookup table & update the average of Risk score in my original feature class attributes.

 

Example:

Material = 3

Operating Pressure = 40

Measured Length = 52.5

Installation Date = 2015-4-01

 

Say overall risk score for Material (3) = 0.3

Say overall risk score for Operating pressure(40) = 0.1

Say overall risk score for Measured Length(52.5) = 1.2

Say overall risk score for Installation Date(2015-4-01) = 1

#And most importantly, I wanna read the "Overall Risk Score" for each parameters not their value, I just want for Operating Pressure =120, what'll be the overall risk score from the lookup table.

Pipe_Risk_Score = (Overall Risk Score (Material) + Overall Risk Score(Operating Pressure)+ Overall Risk Score(Measured Length)+ Overall Risk Score(Installation Date) ) /4

 

That's why I have defined the function, so that i can pass the return average value while updating the field value.

# below is the psuedo code, what i wanna do after the search cursor.

PipeCursor = arcpy.da.UpdateCursor(GDBPath,PipeFCName)
for row in PipeCursor

Material = row[0] // Cast Iron
OperatingPressure = row[1] // 120
MeasuredLength = row[3] // 100
InstallationDate = row[4] // 1-Jan-1990

PipeRiskScore = Pipe_Risk_Score(Material,OperatingPressure,MeasuredLength,InstallationDate)

row.set_value("OverallRiskScore",PipeRiskScore)

Then I have to update it into my feature class by taking all the parameters into consideration.

 

Sir, do you understand now, what i'm trying to do? Now please suggest

0 Kudos
by Anonymous User
Not applicable

Ok, using the cursor example I posted earlier:

 

import arcpy

arcpy.env.workspace = "D:\Pipe\map.gdb"
featureClass_1 = "P_Pipes"
Table_Pipe = "Pipe_Risk"
fieldNames_1 = ["Material", "OPERATINGPRESSURE", "MEASUREDLENGTH", "INSTALLATIONDATE", "Risk_Score"]
fieldNames = ["Material", "OPERATINGPRESSURE", "MEASUREDLENGTHLOWERLIMIT", "MEASUREDLENGTHUPPERLIMIT",
              "INSTALLATIONDATELOWERLIMIT", "INSTALLATIONDATEUPPERLIMIT", "OVERALLRISKSCORE"]


def Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH, INSTALLATIONDATE):
    lst = []
    # Case: Material
    Material_where_Clause = "Material = " + Material
    with arcpy.da.SearchCursor(Table_Pipe, ["Material", "OVERALLRISKSCORE"], Material_where_Clause) as sCur:
        for row in sCur:
            lst.append(row[1])
            Material_Risk_Score = row[1]
            print Material_Risk_Score

    # Case: Operating Pressure
    OP_Out_fields = ["OPERATINGPRESSURE", "OVERALLRISKSCORE"]
    OP_where_Clause = "OPERATINGPRESSURE = " + OPERATINGPRESSURE
    with arcpy.da.SearchCursor(Table_Pipe, OP_Out_fields, OP_where_Clause) as sCur:
        for row in sCur:
            lst.append(row[1])
            OPERATINGPRESSURE_Risk_Score = row[1]
            print OPERATINGPRESSURE_Risk_Score

    # Case: ML
    ML_Out_fields = ["MEASUREDLENGTHLOWERLIMIT", "MEASUREDLENGTHUPPERLIMIT", "OVERALLRISKSCORE"]
    ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= " + MEASUREDLENGTH + " and MEASUREDLENGTHUPPERLIMIT >= " + MEASUREDLENGTH
    print ML_where_Clause
    with arcpy.da.SearchCursor(Table_Pipe, ML_Out_fields, ML_where_Clause) as sCur:
        for row in sCur:
            lst.append(row[2])
            MEASUREDLENGTH_Risk_Score = row[2]
            print MEASUREDLENGTH_Risk_Score

    # Case: ID
    ID_Out_fields = ["INSTALLATIONDATELOWERLIMIT", "INSTALLATIONDATEUPPERLIMIT", "OVERALLRISKSCORE"]
    ID_where_Clause = "INSTALLATIONDATELOWERLIMIT <= {0} and INSTALLATIONDATEUPPERLIMIT >= {0}".format(INSTALLATIONDATE)
    with arcpy.da.SearchCursor(Table_Pipe, ID_Out_fields, ID_where_Clause) as sCur:
        for row in sCur:
            lst.append(row[2])
            ID_Risk_Score = row[2]
            print ID_Risk_Score

    return sum(lst) / len(lst)


with arcpy.da.UpdateCursor(PipeFCName, ["Material", "OPERATINGPRESSURE", "MEASUREDLENGTH", "INSTALLATIONDATE", "Risk_Score"]) as uCur:
    for row in uCur:
        Material = row[0]
        OPERATINGPRESSURE = row[1]
        MEASUREDLENGTH = row[2]
        INSTALLATIONDATE = row[3]

        row[4] = Pipe_Risk_Score(Material, OPERATINGPRESSURE, MEASUREDLENGTH, INSTALLATIONDATE)
        uCur.UpdateRow(row)

 

broy06
by
New Contributor III

I would like to thanks for your continuous effort on my code. Sir, I'm having no problem with "Material & Operating Pressure", but unable to print my 'Installation Date & Measured Length' "Overall Risk score".

The error is in the for loop of Measured Length. Below is the error which i'm getting:

 

Traceback (most recent call last):
File "D:\Arcpy\Material.py", line 51, in <module>
Pipe_Risk_Score("Material", "OPERATINGPRESSURE", "MEASUREDLENGTH", "INSTALLATIONDATE")
File "D:\Arcpy\Material.py", line 35, in Pipe_Risk_Score
for row in sCur:
RuntimeError: An expected Field was not found or could not be retrieved properly. [Pipe_Risk]

 

We're almost done with the code, please tell me how to rectify the same error.

0 Kudos
by Anonymous User
Not applicable

"An expected Field was not found or could not be retrieved properly. [Pipe_Risk]"

Your where clause is not getting the value of MEASUREDLENGTH and is getting 'MEASUREDLENGTH' as a string for that feature.  Does your table have 'MEASUREDLENGTH' mixed in with the values?

I'd try the where cause formatted like this:

ML_where_Clause = "MEASUREDLENGTHLOWERLIMIT <= {0} and MEASUREDLENGTHUPPERLIMIT >= {0}".format(MEASUREDLENGTH)

 

If you see the variable name printed in the where clause (like in the screenshot you shared) and not the expected 3, 4, 1 value, you need to debug why that is happening and write code to handle it.

0 Kudos