2

I'm using an update cursor to iterate through my feature class, create a selection and then delete the row if it meets the condition. It partially works - I get no error messages and the script completes but then a couple of seconds later ArcGIS crashes and the resulting feature class does not have all the selected features removed. I presume I must be using the update cursor incorrectly. Here is my code:

newcur = arcpy.UpdateCursor("outlayer")
for row in newcur:
 if row.LAND1 =="Single Family ( Attached/Detached )" and row.LAND2 =="Single Family ( Attached/Detached )":
 newcur.deleteRow(row)
 newcur.updateRow(row)
 if row.LAND1 =="Multi Family Residential" and row.LAND2 =="Multi Family Residential":
 newcur.deleteRow(row)
 newcur.updateRow(row)
 if row.LAND1 =="Multi Family Residential" and row.LAND2 =="Single Family ( Attached/Detached )":
 newcur.deleteRow(row)
 newcur.updateRow(row)
 if row.LAND1 =="Single Family ( Attached/Detached )" and row.LAND2 =="Multi Family Residential":
 newcur.deleteRow(row)
 newcur.updateRow(row)
 if row.LAND1 =="Public Institutions: Schools" and row.LAND2 =="Public Institutions: Schools":
 newcur.deleteRow(row)
 newcur.updateRow(row)
 if row.LAND1 =="University Semi Govt" and row.LAND2 =="University Semi Govt":
 newcur.deleteRow(row)
 newcur.updateRow(row)
 if row.LAND1=="Park / Recreation / Open Space" and row.LAND2 =="Park / Recreation / Open Space":
 newcur.deleteRow(row)
 newcur.updateRow(row)
del newcur,row
gc.collect()
asked Jan 19, 2016 at 8:55
2
  • Why first delete and then update the row? Ommit the second statement. Commented Jan 19, 2016 at 9:23
  • schoolboy error ... Commented Jan 19, 2016 at 11:30

2 Answers 2

1

I would tackle this problem a little differently. Cursors are great, but you really don't need one here. You basically want to select records according to a giant SQL Query, and delete those records.

First, build up your query bit by bit, to make it more manageable. I would test the selections first individually and as a group:

a = """"LAND1" = 'Single Family ( Attached/Detached )'""" and """"LAND2" = 'Single Family ( Attached/Detached )'"""
b = """"LAND1" = 'Multi Family Residential'""" and """"LAND2" = 'Multi Family Residential'"""
c = """"LAND1" = 'Multi Family Residential'""" and """"LAND2" = 'Single Family ( Attached/Detached )'"""
d = """"LAND1" = 'Single Family ( Attached/Detached )'""" and """"LAND2" = 'Multi Family Residential'"""
e = """"LAND1" = 'Public Institutions: Schools'""" and """"LAND2" = 'Public Institutions: Schools'"""
f = """"LAND1" = 'University Semi Govt'""" and """"LAND2" = 'University Semi Govt'"""
g = """"LAND1" = 'Park / Recreation / Open Space'""" and """"LAND2" = 'Park / Recreation / Open Space'"""
SQLExpression = a + 'OR' + b + 'OR' + c + 'OR' + d + 'OR' + e + 'OR' + f + 'OR' + g 
arcpy.SelectLayerByAttribute_management("outLayer", "NEW_SELECTION", SQLExpression)

Once the appropriate rows are selected, you can delete:

arcpy.DeleteRows_management("outLayer")

Also, I'm generally not a huge fan of deleting data. You might consider writing a definition query, or select the things you don't want in the table, switch the selection, and export the rest to a new feature class.

answered Jan 29, 2016 at 22:05
8
  • Thanks for your suggestion - I tried your suggestion on 21000 records and got <class 'arcgisscripting.ExecuteError'>: ERROR 000426: Out Of Memory Failed to execute (SelectLayerByLocation) - I have 64bit OS and 24GB - looking into why this would crash in model builder and will get back to you. Commented Feb 16, 2016 at 14:47
  • Additionally I have tried it in the Python window without sucess: >>> a = '"LAND1" = Single Family ( Attached/Detached ) and "LAND2" = Single Family ( Attached/Detached )' >>> SQLExpression = a >>> arcpy.SelectLayerByAttribute_management("outlayer","NEW_SELECTION",SQLExpression) Runtime error <class 'arcgisscripting.ExecuteError'>: ERROR 000358: Invalid expression Failed to execute (SelectLayerByAttribute). Commented Feb 16, 2016 at 15:20
  • The SQLExpression containing backslashes created for 'g' does not work. Considering how I can pass this using some other means Commented Feb 17, 2016 at 10:52
  • For your first question here, you should be selecting by attribute, not location. For question #2, double check that your strings are exactly as they appear in your data, including spaces. For questions #2 & #3, python might be interpreting your backslashes as escapes. Try making the SQL statements into raw strings (e.g. r'string stuff'). See the discussion here: stackoverflow.com/q/301068/5641121 Commented Feb 19, 2016 at 16:32
  • Apologies, question #1 occurred due to an error in a different part (unrelated) of the script. For #2&#3 - I have no control over the attribute values and it seems that the multiple backslashes are causing the problem. I have tried to create a code object for the following selection: "LAND1"= 'Park / Recreation / Open Space' AND "LAND2"= 'Park / Recreation / Open Space' I have tried various incarnations of : code_string = """"LAND1"= 'Park / Recreation / Open Space'""" code_obj = compile(code_string,'<string>', 'exec') This gives an error. Can I use code objects in this way? Commented Feb 28, 2016 at 14:34
1

First you don't need to use updateRow() when you delete a row.

Also, all your conditions are exclusive, so using elif instead of if would be neater and probably speed up your code a little bit.

And third, calling the garbage collector gc.collect() is pretty useless here, just remove it.

So your code would look like this:

newcur = arcpy.UpdateCursor("outlayer")
for row in newcur:
 if row.LAND1 =="Single Family ( Attached/Detached )" and row.LAND2 =="Single Family ( Attached/Detached )":
 newcur.deleteRow(row)
 elif row.LAND1 =="Multi Family Residential" and row.LAND2 =="Multi Family Residential":
 newcur.deleteRow(row)
 elif row.LAND1 =="Multi Family Residential" and row.LAND2 =="Single Family ( Attached/Detached )":
 newcur.deleteRow(row)
 elif row.LAND1 =="Single Family ( Attached/Detached )" and row.LAND2 =="Multi Family Residential":
 newcur.deleteRow(row)
 elif row.LAND1 =="Public Institutions: Schools" and row.LAND2 =="Public Institutions: Schools":
 newcur.deleteRow(row)
 elif row.LAND1 =="University Semi Govt" and row.LAND2 =="University Semi Govt":
 newcur.deleteRow(row)
 elif row.LAND1=="Park / Recreation / Open Space" and row.LAND2 =="Park / Recreation / Open Space":
 newcur.deleteRow(row)
del newcur,row
answered Jan 19, 2016 at 9:24
4
  • Unfortunately this still does not work.....executing it in the Python window actually reports a syntax error with the if statements. This hadn't happened with the script running in model builder which as I mentioned completed without errors. Commented Jan 19, 2016 at 11:13
  • I have tried using SelectLayerByAttribute_management within the update cursor loop utilizing a predefined where clause for each condition but run into similar problems. Commented Jan 19, 2016 at 11:27
  • What is your syntax error? Where do you actually run your script, in ArcMap/ArcCatalog/other IDE? From the Python window, ModelBuilder, or script tool? What is "outlayer", a feature class on your disc or a layer in the TOC? Commented Jan 19, 2016 at 12:06
  • It is running as script in Modelbuilder in ArcMap. The script creates an on my disk just prior to this step and then I used make feature layer to create 'outlayer'. I just tried the select by attribute option in the python window. Commented Jan 19, 2016 at 14:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.