4

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.

  • 1
    That should be arcpy.da.UpdateCursor(inFeatures,['x','y','shape@']) assuming fields 'x' and 'y' exist, if you're after the shapes' X and Y it should be arcpy.da.UpdateCursor(inFeatures,['shape@x','shape@y','shape@']). Schema locks are because you have something open in multiple instances (also if you've looked at something in Catalog and moved on, the lock remains). No, you don't need to set your workspace, it defaults to whatever you've set in your environments. row[1] = row[2].lastPoint.X shouldn't that be row[1] = row[2].firstPoint.Y for the 'y' field? – Michael Stimson Dec 18 '14 at 2:38
  • Layers are a representation. Add the field to the layer's feature class then re-make the layer. When adding fields to a layer it is not uncommon for the layer to not have the newly added field. – Michael Stimson Dec 18 '14 at 2:41
  • Sorry for the confusion, I am only calculating first and last x points, I should have used a different letter than 'Y'. x1 and x2 would be better. – JrUser Dec 18 '14 at 3:42
  • Easy fixed. See edits. That's the benefit of putting the fields into a list - only needs to be changed once, good forward planning there! – Michael Stimson Dec 18 '14 at 3:45
3

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.

  • Thank you for the answer(s) @Michael, really good explanation! – JrUser Dec 18 '14 at 3:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.