Email from Python 2.7.x to 3.x

596
3
Jump to solution
08-27-2020 10:30 AM
Brian_McLeer
Occasional Contributor II

In trying to migrate Python Scripts from ArcGIS Desktop Python 2.7.x to ArcGIS Pro 3.x, we email staff if there is a failure on a routine. Below I am running a sync replica routine using ArcGIS Pro, deliberately breaking it on the file path to the database connection string so it will email a failure. Somewhere in migration, it does not like the email code that has been working for years now. Has anyone else had to upgrade email failures from 2.7.x to 3.x in Python? With using the correct file path, the routine was successful. We use Windows Task Scheduler to run Python routines. 

I receive the error (server name omitted for security): 

try:
			arcpy.management.SynchronizeChanges(r"C:\Tech_Info\DB_CONX\SERVER\SERVER ParentDatabase user.sde", "ReplicaName", r"C:\Tech_Info\DB_CONX\Server\SERVER ChildDatabase user.sde", "FROM_GEODATABASE1_TO_2", "IN_FAVOR_OF_GDB1", "BY_OBJECT", "RECONCILE ")
except Exception as e:
			arcpy.AddMessage("SynchronizeChanges_management ISGIS.ReplicaName Failed..." +'\n')
			txtFile.write("SynchronizeChanges_management ISGIS.ReplicaName Failed..." +'\n')
			txtFile.write (arcpy.GetMessages() + '\n')
			HOST = "host.server.com"
			SUBJECT = "Priority: CRITICAL Routine Failure"
			TO = "email@python.org"
			FROM = "Routine Failure<failure@python.org>"
			text = "Routine has failed. Please see log file for detailed information. \n Error Message: \n " + str(e.msg)
			BODY = string.join((
				"From: %s" % FROM,
				"To: %s" % TO,
				"Subject: %s" % SUBJECT,
				"",
				text
			), "\r\n")
			server = smtplib.SMTP(HOST)
			server.sendmail(FROM, [TO], BODY)
			server.quit()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Brian
0 Kudos
1 Solution

Accepted Solutions
MichaelBoyce
Esri Contributor

Hi Brian McLeer‌,

Looking at the screen grab, it looks like the error is in the following line:

 text = "Routine has failed. Please see log file for detailed information. \n Error Message: \n " + str(e.msg)

You are trying to call the "msg" of the exception.  You should be able to just call e to get the result you are after.

Also, using the "{}".format("") syntax for strings should clean up the code a little and will automatically convert things into the correct format.

Try this:

try:
    arcpy.management.SynchronizeChanges(r"C:\Tech_Info\DB_CONX\SERVER\SERVER ParentDatabase user.sde", "ReplicaName", r"C:\Tech_Info\DB_CONX\Server\SERVER ChildDatabase user.sde", "FROM_GEODATABASE1_TO_2", "IN_FAVOR_OF_GDB1", "BY_OBJECT", "RECONCILE ")
except Exception as e:
   arcpy.AddMessage("SynchronizeChanges_management ISGIS.ReplicaName Failed...{0}".format('\n'))
   txtFile.write("SynchronizeChanges_management ISGIS.ReplicaName Failed...{0}".format('\n'))
   txtFile.write("{0}{1}".format(arcpy.GetMessages(), '\n'))
   HOST = "host.server.com"
   SUBJECT = "Priority: CRITICAL Routine Failure"
   TO = "email@python.org"
   FROM = "Routine Failure<failure@python.org>"
   text = "Routine has failed. Please see log file for detailed information. \n Error Message: \n {0}".format(e)
   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()

I hope this helps,

Michael

edit: Fixed up the indentation in the code block

View solution in original post

3 Replies
MichaelBoyce
Esri Contributor

Hi Brian McLeer‌,

Looking at the screen grab, it looks like the error is in the following line:

 text = "Routine has failed. Please see log file for detailed information. \n Error Message: \n " + str(e.msg)

You are trying to call the "msg" of the exception.  You should be able to just call e to get the result you are after.

Also, using the "{}".format("") syntax for strings should clean up the code a little and will automatically convert things into the correct format.

Try this:

try:
    arcpy.management.SynchronizeChanges(r"C:\Tech_Info\DB_CONX\SERVER\SERVER ParentDatabase user.sde", "ReplicaName", r"C:\Tech_Info\DB_CONX\Server\SERVER ChildDatabase user.sde", "FROM_GEODATABASE1_TO_2", "IN_FAVOR_OF_GDB1", "BY_OBJECT", "RECONCILE ")
except Exception as e:
   arcpy.AddMessage("SynchronizeChanges_management ISGIS.ReplicaName Failed...{0}".format('\n'))
   txtFile.write("SynchronizeChanges_management ISGIS.ReplicaName Failed...{0}".format('\n'))
   txtFile.write("{0}{1}".format(arcpy.GetMessages(), '\n'))
   HOST = "host.server.com"
   SUBJECT = "Priority: CRITICAL Routine Failure"
   TO = "email@python.org"
   FROM = "Routine Failure<failure@python.org>"
   text = "Routine has failed. Please see log file for detailed information. \n Error Message: \n {0}".format(e)
   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()

I hope this helps,

Michael

edit: Fixed up the indentation in the code block

Brian_McLeer
Occasional Contributor II

Thank you, Michael, that did work. This will be helpful as we will have parallel Python environments of 2.7.x and 3.x until we can fully migrate to ArcGIS Pro. 

Brian
0 Kudos
DanDeegan
New Contributor III

One thing you have to look forward to in python 3 are f strings. They are so helpful when trying to make sql expressions. 

https://docs.python.org/3/reference/lexical_analysis.html#f-strings