[GIS] Do I need to set arcpy.env.workspace at the beginning of the python code

arcgis-10.1arcpycursor

I am new to Arcpy and have been doing simple tasks such as AddField_management and updateCursor. However I have been getting error msgs, such as errors 99999 etc. The errors I get are related to schema lock or layer not refreshing. So I need to run part of the code, close my mxd and open it again,do this over and over.

I am probably doing something wrong or forgetting something. Per example, I am not setting env.workspace or in_memory or creating temp _lyr files.
This is an example of a simple code I am using, from start to finish.

inFeatures = "MyLayer"
fields = ['x','y']

# Add fields to your inFeatures
for field in fields:
    arcpy.AddField_management(inFeatures,str(field),"DOUBLE")

with arcpy.da.UpdateCursor(inFeatures, ('x','y',"shape@")) as cursor:
    for row in cursor:
        row[0] = row[2].firstPoint.X
        row[1] = row[2].lastPoint.X
        cursor.updateRow(row)

I get the following errors, 'x' was created by 'y' wasnt. I close my mxd and open it again, and I can see field 'y'. Now I run UpdateCursor, nothing changes (still see Null> values). Or I get the error

A column was specified that does not exist

I close the mxd, open it again and I can see the updated columns. This is happening for all my codes, not only this one (ie. not refreshing). My question is, do I need, always, to set my env.workspace?
I am running ArcGIS 10.1, files are feature datasets, using Python window in ArcGIS, file path is not long, layers do not have spaces.

Best Answer

Your basic code is very good. As per my comments:

arcpy.da.UpdateCursor(inFeatures, ('x','y',"shape@")) 

should be

arcpy.da.UpdateCursor(inFeatures,['x','y','shape@'])

The square brackets make it a list which is what the tool is expecting.

Schema locks occur when you have the same data open in multiple sources or have left a cursor unclosed - using with ensures that the cursor gets closed properly. You can consider including error-checking for locks using try: except: blocks.

When adding a field to a layer object it is not uncommon for the new field to be inaccessible in the layer, so it's best to add the field to the data source and re-make the layer. You can get the datasource from the layer as it's one of the layer objects properties.

import arcpy, sys

inFeatures = "MyLayer"
fields = ["x1","x2"] # already strings, don't need to str() later
ds = inFeatures.dataSource
dq = inFeatures.definitionQuery # the query used to make the layer

# Add fields to your inFeatures
for field in fields:
    try:
        arcpy.AddField_management(ds,field,"DOUBLE")
    except:
        arcpy.AddError("Unable to add field " + field)
        sys.exit(-1) # abandon the script

# Remake the layer
arcpy.Delete_management("MyLayer") # you don't need to do this if you set arcpy.env.overwriteOutput = True
arcpy.MakeFeatureLayer_management(ds,"MyLayer",dq) 

# with arcpy.da.UpdateCursor(inFeatures, ['x','y',"shape@"]) as cursor:
# another way to do this:
fields.append("shape@")
with arcpy.da.UpdateCursor(inFeatures, fields) as cursor:
    for row in cursor:
        row[0] = row[2].firstPoint.X # X coordinate of first point
        row[1] = row[2].lastPoint.X # X coordinate of last point
        cursor.updateRow(row)

You don't need to set arcpy.env.workspace, it will default to what's already set in the geoprocessing environments, which is set during installation to your home folder (C:\Users\your_name\Documents\ArcGIS\Default.gdb).

Specifying the workspace is important for functions like ListFeatureClasses which return names of feature classes only (not paths); any input/output without a full path will be considered to be referenced to the current workspace, so arcpy.MakeFeatureLayer("data","data_layer") will be looking in your current workspace for a feature class called "data" to make the layer from - it can save some typing in these cases.