I need some help with some nested Search/Insert Cursors adding data to a table and to a point feature class.
I would be very happy if someone could push me in the right direction to make this work.
Here is simplified version of my module:
table=input table
fieldnames = [field names from input table except OBJECTID]
pfields=arcpy.ListFields(points)
fillnames=[field names for point feature class, manually created, not OBJECTID, not SHAPE]
# Create cursors and insert new rows
for profile in profile_nrs:
expression="Station="+str(profile)
with arcpy.da.SearchCursor(table,fieldnames,expression) as sCursor:
for sRow in sCursor:
table_name=str(sRow[0])+"_"+str(sRow[1])+"_data1"
with arcpy.da.InsertCursor(table_name,fieldnames) as iCursor:
for sRow in sCursor: -> This is where I get the RuntimeError
iCursor.insertRow(sRow)
del iCursor
del sRow
del sCursor
print("Table "+table_name+" filled")
# From here starts the point feature creation
#Identify first OBJECTID used in new table
oid_nrs=unique_values(table_name, "OBJECTID")
FirstObject=oid_nrs[0]
#Define expression to limit the extracted rows to the first row
pexpression="OBJECTID="+str(oid_nrs[0])
#Define field names used for point table
pfieldnames=['Cruise','Station', 'Type', 'Date', 'Longitude', 'Latitude']
print(pfieldnames)
pfieldsvalues=[FirstObject]
for pname in pfieldnames:
with arcpy.da.SearchCursor(table_name, pname, pexpression) as pCursor:
for pRow in pCursor:
fillvalue=pRow[0]
print(fillvalue)
pfieldsvalues.append(fillvalue)
ShapeVal=[pfieldsvalues[5],pfieldsvalues[6]]
print(fillnames)
#take the values extracted from the first row in the new table and put
#them into a new array adding OBJECTID and Shape (Geometry)
fillValues=[pfieldsvalues[0], ShapeVal, pfieldsvalues[1], pfieldsvalues[2], pfieldsvalues[3], pfieldsvalues[4], pfieldsvalues[5], pfieldsvalues[6]]
print(fillValues)
newPoint=arcpy.da.InsertCursor(points, fillnames)
newPoint.insertRow(fillValues)
print("point added to All_points")
del pRow
del pCursor
Without really trying to figure out exactly what is going on here....
with arcpy.da.SearchCursor(table,fieldnames,expression) as sCursor:
for sRow in sCursor:
table_name=str(sRow[0])+"_"+str(sRow[1])+"_data1"
with arcpy.da.InsertCursor(table_name,fieldnames) as iCursor:
for sRow in sCursor: -> This is where I get the RuntimeError
iCursor.insertRow(sRow)
del iCursor
del sRow
del sCursor
print("Table "+table_name+" filled")
You are going through sCursor twice here. Then you are deleting it inside the loop.
You don't need a with statement for the InsertCursor. I would open the insert outside of the loop.
Thank you Neil for looking into this.
Although your comment makes totally sense to me it seems like I created now an endless loop that doesn't allow the module to be finished.
with arcpy.da.SearchCursor(table,fieldnames,expression) as sCursor:
for sRow in sCursor:
table_name=str(sRow[0])+"_"+str(sRow[1])+"_data1"
iCursor=arcpy.da.InsertCursor(table_name,fieldnames)
iCursor.insertRow(sRow)
del iCursor
del sRow
del sCursor
print("Table "+table_name+" filled")
When I have the del sCursor in line 8 it says there is no sCursor, when I remove it and put it to the end then it runs without ending.
It seems to establish the table_name correctly but only that.
Any idea why my point is not created?
your del statements... are they meant to be within the for loop? within the while loop? or do you simply want them deleted when you are done? From the above, dedent the del statements appropriately
Thanks for the hint. I think I indented/detended them the way it should be (from my understanding I should delete them at the end of the according loop).
okaaaaayyyyy, thinking through this I think the problem is, that it tries to create the table every time the sCursor reaches a new sRow. I guess this is why I had put an extra loop before for filling the table.
Which still doesn't explain why the point is not created...
because your cursors are deleted within the loop
with arcpy.da.SearchCursor(table,fieldnames,expression) as sCursor: # you open the cursor
for sRow in sCursor: # and start reading each row
table_name=str(sRow[0])+"_"+str(sRow[1])+"_data1" # conduct some table identifier
iCursor=arcpy.da.InsertCursor(table_name,fieldnames) # open cursor and insert row
iCursor.insertRow(sRow)# i hope that table_name exists and fieldnames are compatible
del iCursor # this is okay in this context
del sRow # but woah, why am I deleting the row, it will be recreated on next look anyway
del sCursor # and now I have deleted the cursor itself
# that's why you get an error on the second time round the read.
print("Table "+table_name+" filled")
Just to get back to this little bit of code...
So, with statements are supposed to obviate the need to delete the cursor objects anyway. They are deleted auto magically after the with closes.
Basically, don't delete your cursor object while the loop is still reading it.
I think the problem is still somehow how the loops are nested.
At which point would you suggest to delete the sCursor?
Alternatively to using nested cursors, I suggest taking a look at Richard Fairhurst excellent blog post about using dictionaries and cursors for data manipulation. Should also give you a significant performance boost in processing time.