Fill table with update cursor? array?

743
6
Jump to solution
09-20-2019 12:24 AM
JohannesBierer
Regular Contributor

Hello,

I have problems to update two attribute fields with values created in the following code. The insert cursor works well but with the update cursor I get a error message. Are there any other ways to fill a table with values?

Error message:

line 60, in UpdateFields
    cursor.updateRow([row])
StopIteration: iteration not started

# -*- coding: cp1252 -*-
import arcpy, os

arcpy.env.overwriteOutput = True

myPath = r"R:\Daten\geo_daten\Arten\Fledermaeuse\AltDaten"
out_path_table = r"C:\temp4\Geodatenbestand.mdb"
out_name_table = "Geodatenbestand"
template_table = r"C:\temp4\Geodatenbestand.mdb\Geodatenbestand_Template"
inTable = os.path.join(out_path_table, out_name_table)
inTableL = "Table_Layer"

MyList1 = list()
MyList2 = list()

# Encoding der Standardausgabe herausfinden
stdout_encoding = sys.stdout.encoding or sys.getfilesystemencoding()

class Geodatenbestand(object):

    def __init__(self):

        self.myPath = myPath       

    def SearchFiles(self):
        
        SHPCounter = 0
                
        for path, dirs, files in os.walk(myPath):
            for file in files:
                if file.lower().endswith('.shp'):
                    print path + "\\" + file
                    
                    SHPCounter += 1
                    print SHPCounter
                    
                    accessTime = os.path.getatime(os.path.join(path, file)) # last access time
                    
                    actualTime = time.time()

                    hoursPassed = """{}""".format(int((actualTime - accessTime)/3600))

                    path1 = path.decode(stdout_encoding)
                    file1 = file.decode(stdout_encoding) 
                    print file1
                    
                    cursor = arcpy.da.InsertCursor(inTable, ['PathFile'])
                    cursor.insertRow([path1 + "\\" + file1])

                    MyList1.append(file1)
                    MyList2.append(hoursPassed)

    def UpdateFields(self):
        
        print MyList1
                        
        with arcpy.da.UpdateCursor(inTable,["File"]) as cursor:
            for row in MyList1:
                
                cursor.updateRow([row])

        print MyList2
        
        with arcpy.da.UpdateCursor(inTable,["h_not_used"]) as cursor:
            for row in MyList2:
                
                cursor.updateRow([row])
              

    def CreateTable(self):
        
        if arcpy.Exists(inTable):
            arcpy.Delete_management(inTable)
        arcpy.CreateTable_management(out_path_table, out_name_table, template_table)
 
        
if __name__ == '__main__':

    MyClass = Geodatenbestand()
    
    MyClass.CreateTable()
    MyClass.SearchFiles()
    MyClass.UpdateFields()
    


‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

Actually, your code is worse than you think.  You are writing, and overwriting, each and every value in MyList1 into each and every row in cursor.  Since the last value isn't overwritten, that is what you are seeing in each row after the update cursor is complete.

Assuming the cursor and list are the same length, and the cursor will iterate in the same order as the list, which is a risky assumption when not using a SQL ORDER BY clause, you could go with:

with arcpy.da.UpdateCursor(inTable,["File"]) as cursor:
    for value in MyList1:
        next(cursor)
        cursor.updateRow([value])

View solution in original post

0 Kudos
6 Replies
JohannesBierer
Regular Contributor

If you use a array, how to fill a column in an array with a list? This doesn't work:

def UpdateFields(self):
               
        inArray = numpy.array([(MyList, MyList1, MyList2)],
                      numpy.dtype([('Path_File', '|S256'),
                                   ('File', '|S256'),
                                   ('h_not_used', numpy.int32)]))
        
        arcpy.da.NumPyArrayToTable(inArray, outTable)

Error message:

line 63, in UpdateFields
    ('h_not_used', numpy.int32)]))
ValueError: cannot set an array element with a sequence

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

For NumPy, try this:

inArray = numpy.array(
    [(i,j,k) for i,j,k in zip(MyList,MyList1,MyList2)],
    numpy.dtype([('Path_File', '|S256'),('File', '|S256'),('h_not_used', numpy.int32)])
)
JoshuaBixby
MVP Esteemed Contributor

Simply looking at this error:

Error message:

line 60, in UpdateFields
    cursor.updateRow([row])
StopIteration: iteration not started

In Line #57, you instantiate the cursor but you never start iterating through it.  Whereas most or all geoprocessing tools work on sets of data, ArcPy cursors work on individual rows of data. 

You will run into the same error on Lines #64-#67.

JohannesBierer
Regular Contributor

Yes OK.

If I write it like this it overwrites all rows with the last value in MyList1. Don't really know how to get it to write exactly each row in the list into the right row in the table?

  def UpdateFields(self):
        
        print MyList1
                        
        with arcpy.da.UpdateCursor(inTable,["File"]) as cursor:
            for row in cursor:
                for value in MyList1:
                    print value
                    cursor.updateRow([value])
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Actually, your code is worse than you think.  You are writing, and overwriting, each and every value in MyList1 into each and every row in cursor.  Since the last value isn't overwritten, that is what you are seeing in each row after the update cursor is complete.

Assuming the cursor and list are the same length, and the cursor will iterate in the same order as the list, which is a risky assumption when not using a SQL ORDER BY clause, you could go with:

with arcpy.da.UpdateCursor(inTable,["File"]) as cursor:
    for value in MyList1:
        next(cursor)
        cursor.updateRow([value])
0 Kudos
JohannesBierer
Regular Contributor

Thank you ...

0 Kudos