Depending on your needs, you might want to wrap your geoprocessing functions within a Try/Except block. We have several scripts that we run in off hours so if something goes south, we like to get an email telling us so. The except block invokes the sendEmail() def. We also like to log all the processes so we can see what worked and what didn't:
def createAliasTable(msdCenterlines,centerlinesAlias,logoutput):
defName = 'Create Alias Table'
try:
select = "NAME >= 'A'"
arcpy.management.MakeFeatureLayer(msdCenterlines, 'centerlinesLyr', select)
arcpy.TruncateTable_management(centerlinesAlias)
arcpy.management.Append('centerlinesLyr',centerlinesAlias,'NO_TEST')
createTime = time.strftime('%Y-%m-%d %H:%M:%S')
logoutput.write(f'Success: completed {defName} at {createTime}\n')
except Exception as err:
failTime = time.strftime('%Y-%m-%d %H:%M:%S')
logoutput.write(f'Failure: Unable to complete {defName} at {failTime}\n ')
logoutput.write(f'{err}\n')
sendEmail(err)
Using the try/except approach, if the script tosses an error somewhere along the line, it won't totally blow up and shut down. We standardize all of our scripts with geoprocessing defs and call them from the main def, passing variables as arguments/parameters set there.
def main():
logFile = r"N:\GIS\Scripts\Logs\CreateCityWorksLocator.txt"
if os.path.exists(logFile):
os.remove(logFile)
logoutput = open(logFile,'a')
startUp(logoutput)
#set input parameters for various defs()
ws = r'N:\GIS\Geocoding\CityWorksLocators\GeocodingData.gdb'
sde = r'\\path\to\connectionFile\SLCOmsd@MSD.sde'
municipalities = f'{sde}\MSD.SLCOMSD.MunicipalitiesMSD'
centerlinesAlias = f'{ws}\CenterlinesMSD_Alias'
locatorDir = r'N:\GIS\Geocoding\CityWorksLocators\Locators\Joes'
parcels = r'J:\ConnectionFile\aDifferent.sde\MSD.SLCOMSD.SLCo_Parcels'
slcoCenterlines = f'{sde}\MSD.SLCOMSD.SLCo_Centerlines'
slcoAddressPoints = f'{sde}\MSD.SLCOMSD.SLCo_AddressPoints'
msdCenterlines = f'{sde}\MSD.SLCOMSD.CenterlinesMSD'
msdAddressPoints = f'{sde}\MSD.SLCOMSD.SiteAddressPointsMSD'
msdFgbAddressPoints = f'{ws}\SiteAddressPointsMSD'
#call the defs comment out as needed for testing purposes
#arcelsToFGDB(parcels,ws,municipalities,logoutput)
#createParcelLocator(parcels,locatorDir,logoutput)
#createNonMsdParcelLocator(ws,locatorDir,logoutput)
#createAliasTable(msdCenterlines,centerlinesAlias,logoutput)
#nonMsdAddressPoints(ws,slcoAddressPoints,municipalities,logoutput)
#nonMsdCenterlines(ws,slcoCenterlines,municipalities,logoutput)
#nonMsdLocator(ws,locatorDir,logoutput)
#createMsdAddressPoints(ws,msdAddressPoints,logoutput)
#msdLocator(ws,centerlinesAlias,msdFgbAddressPoints,msdCenterlines,locatorDir,logoutput)
compositeLocator(locatorDir,logoutput)
if __name__ == '__main__':
main()
Notice that all the calls to the various defs are commented out; with a modular approach, you can only run the defs you want to.
That should just about do it....