Friday, 19 April 2019

arcpy - SearchCursor() fails to read feature class?


I am very new to ArcPy and Python in general. I want write a script to read attribute table from a feature class and merge some data from a csv file into the table. Right now, I am just playing around with the table just to make sure everything is fine, so here is the code:


fc = 'ShuttleStop_nextbus'
cursor = arcpy.SearchCursor(fc, '*', """ 'NextBus_nu' = '27837' """)
for row in cursor:

print row

(I have set arcpy.env.workspace to current workspace)


So I inspected the content of the feature class with


len(arcpy.ListFields("ShuttleStop_nextbus"))

It return 13, which is exactly the number of fields. Then I read all the fields with


fields = arcpy.ListFields("ShuttleStop_nextbus")
for f in fields: print f


Then, it outputs something like this:








.........
.........


Turns out the fields are actually of type Describe.


Is there anyway that I can query the table if all the above occurs? I still want to use the "where" clause of SearchCursor(). Let me know if I need to clarify something.



Answer



Confusingly, there are two different types of cursors: the "classic" cursors of Arc 10.0 and the arcpy.da cursors of Arc 10.1.




Arc 10.0 - "Classic" cursors



  • When using classic cursors (i.e. arcpy.SearchCursor) the cursor object is an iterable containing row objects. You need to use the getValue method to retrieve the data from the row.

  • The second parameter for arcpy.SearchCursor is your where clause, so you don't need the "*" parameter in there.

  • Your where clause is not set up properly, since Arc needs to have field names delimited by double quotes. To handle this with Python's use of quotes as string delimiters, you need to use the backslash escape character.



Here's a code sample with fixes applied:


fc = 'ShuttleStop_nextbus'
#List comprehension creates list of field names to read
fieldsList = [field.name for field in arcpy.ListFields("ShuttleStop_nextbus")]
cursor = arcpy.SearchCursor(fc, "\"NextBus_nu\" = '27837'")
for row in cursor:
for field in fieldsList: #Iterate through field names
print row.getValue(field) #Print value of this field for this row




Arc 10.1 - arcpy.da cursors



  • When using the new cursors in the data access module (i.e. arcpy.da.SearchCursor) you need to pass in a list of field names as the second parameter in the cursor constructor. This requires some more work up-front, but the resulting row objects are Python lists, which makes it easier to read data when iterating through cursor rows. arcpy.da.SearchCursor also has better performance than arcpy.SearchCursor, partially because it skips unimportant fields, especially geometry.

  • As before, your where clause is not set up properly, since Arc needs to have field names delimited by double quotes. To handle this with Python's use of quotes as string delimiters, you need to use the backslash escape character.


Here's a code sample with fixes applied:


fc = 'ShuttleStop_nextbus'
#List comprehension creates list of field names to read
fieldsList = [field.name for field in arcpy.ListFields("ShuttleStop_nextbus")]

cursor = arcpy.da.SearchCursor(fc, fieldsList , "\"NextBus_nu\" = '27837'")
for row in cursor:
for cell in row: #Iterate through row, which is a Python list
print cell #Print value of item in row list

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...