In migrating from Python 2.x to 3.x, we had a process that emails water accounts that are unable to be geocoded and added to our meter feature class. There was no change to the schema, but recently we had the below failure. The field still exists named 'MunisAccount' in the NewAccountsGeocoded feature class.
Error received:
Row: Field MunisAccount does not exist
arcpy.MakeFeatureLayer_management("D:\\WorkSpace\\Water\\Workspace.gdb\\NewAccountsGeocoded", "NewAccountsGeocoded_Layer", "", "", "")
arcpy.SelectLayerByAttribute_management("NewAccountsGeocoded_Layer", "NEW_SELECTION", "Status NOT IN ( 'M', 'T')")
for row in arcpy.SearchCursor("NewAccountsGeocoded_Layer"):
print (row.MunisAccount, row.ARC_Single_Line_Input)
arcpy.AddMessage("Water_ID_Updates Failed...{0}".format('\n'))
txtFile.write("Water_ID_Updates Failed...{0}".format('\n'))
txtFile.write("{0}{1}".format(arcpy.GetMessages(), '\n'))
HOST = "server.host.com"
SUBJECT = "Report: Unable to Add UB Accounts to GIS Accounts"
TO = "brian@email.com"
FROM = "Water Accounts<email@email.com>"
text = "The following UB Account was not able to be imported into GIS WtrAccounts. Please see if there is an error in UB or if the address exists in COH Address GIS feature class. \n " + "UB Account: "+str(row.MunisAccount) + " | UB Address: "+str(row.ARC_Single_Line_Input)+"\n"
BODY = "From: {1}{0}To: {2}{0}Subject: {3}{0}{0}{4}".format('\r\n', FROM, TO, SUBJECT, text)
server = smtplib.SMTP(HOST)
server.sendmail(FROM, [TO], BODY)
server.quit()
Solved! Go to Solution.
Then the multiple addresses must be in a list that you cycle through?
Are you sure you aren't missing some code from the original since I thought this was just a python 2 to 3 conversion?
There have been no changes in how python functions at the level of missing lists versus single entries. Is this what the changes in the input field names is all about?
You should use the data access cursors now
SearchCursor—ArcGIS Pro | Documentation
SearchCursor (in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause}, {datum_transformation})
Either provide the field names you need or use "*" as the wildcard for all fields
Thank you Dan,
I updated the code below for lines 2, 3, and 4 based on the ESRI documentation, and still getting the error the field 'MunisAccount' does not exist. My guess is something in row 5 or row 13 is the issue?
arcpy.SelectLayerByAttribute_management("NewAccountsGeocoded_Layer", "NEW_SELECTION", "Status NOT IN ( 'M', 'T')")
fc = "D:\\WorkSpace\\Water\\Workspace.gdb\\NewAccountsGeocoded"
fields = ['MunisAccount']
for row in arcpy.SearchCursor(fc, fields):
print((row.MunisAccount, row.ARC_Single_Line_Input))
arcpy.AddMessage("Water_ID_Updates Failed...{0}".format('\n'))
txtFile.write("Water_ID_Updates Failed...{0}".format('\n'))
txtFile.write("{0}{1}".format(arcpy.GetMessages(), '\n'))
HOST = "server.host.com"
SUBJECT = "Report: Unable to Add UB Accounts to GIS Accounts"
TO = "brian@email.com"
FROM = "Water Accounts<email@email.com>"
text = "The following UB Account was not able to be imported into GIS WtrAccounts. Please see if there is an error in UB or if the address exists in COH Address GIS feature class. \n " + "UB Account: "+str(row.MunisAccount) + " | UB Address: "+str(row.ARC_Single_Line_Input)+"\n"
BODY = "From: {1}{0}To: {2}{0}Subject: {3}{0}{0}{4}".format('\r\n', FROM, TO, SUBJECT, text)
server = smtplib.SMTP(HOST)
server.sendmail(FROM, [TO], BODY)
server.quit()
row[0]
and if you are going to use row.ARC_Single_Line_Input you had better add that field to your field list and it will become row[1]
So I got the code to work and email to a single address like the commented out line 11, but in trying to send to multiple email addresses like in line 10 it fails with the error message below.
unhashable type: 'list'
fc = "D:\\WorkSpace\\Water\\Workspace.gdb\\NewAccountsGeocoded"
fields = ['USER_MunisAccount','IN_Single_Line_Input']
qry = "Status NOT IN ( 'M', 'T')"
with arcpy.da.SearchCursor(fc, fields, qry) as cursor:
for row in cursor:
print(row [0], row [1])
txtFile.write("{0}{1}".format(arcpy.GetMessages(), '\n'))
HOST = "server.email.com"
SUBJECT = "Report: Unable to Add UB Accounts to GIS Accounts"
TO = ["symon@email.com","dave@email.com","brian@email.com"]
#TO = "brian@email.com"
FROM = "Water Accounts<GIS@email.com>"
text = "The following UB Account was not able to be imported into GIS WtrAccounts. Please see if there is an error in UB or if the address exists in COH Address GIS feature class. \n " + "UB Account: "+str(row[0]) + " | UB Address: "+str(row[1])+"\n"
BODY = "From: {1}{0}To: {2}{0}Subject: {3}{0}{0}{4}".format('\r\n', FROM, TO, SUBJECT, text)
server = smtplib.SMTP(HOST)
server.sendmail(FROM, [TO], BODY)
server.quit()
Then the multiple addresses must be in a list that you cycle through?
Are you sure you aren't missing some code from the original since I thought this was just a python 2 to 3 conversion?
There have been no changes in how python functions at the level of missing lists versus single entries. Is this what the changes in the input field names is all about?
Had to make some updates, but the below solution worked.
fc = "D:\\WorkSpace\\Water\\Workspace.gdb\\NewAccountsGeocoded"
fields = ['USER_MunisAccount','IN_Single_Line_Input']
qry = "Status NOT IN ( 'M', 'T')"
with arcpy.da.SearchCursor(fc, fields, qry) as cursor:
for row in cursor:
print(row [0], row [1])
txtFile.write("{0}{1}".format(arcpy.GetMessages(), '\n'))
HOST = "server.domain.com"
SUBJECT = "Report: Unable to Add UB Accounts to GIS Accounts"
TO = "symon@email.com", "dave@email.com", "brian@email.com"
FROM = "Water Accounts<GIS@email.com>"
text = "The following UB Account was not able to be imported into GIS WtrAccounts. Please see if there is an error in UB or if the address exists in COH Address GIS feature class. \n " + "UB Account: "+str(row[0]) + " | UB Address: "+str(row[1])+"\n"
BODY = "From: {1}{0}To: {2}{0}Subject: {3}{0}{0}{4}".format('\r\n', FROM, TO, SUBJECT, text)
server = smtplib.SMTP(HOST)
server.sendmail(FROM, TO, BODY)
server.quit()