Zugreifen auf Daten mit Cursorn

Ein Cursor ist ein Datenzugriffsobjekt, mit dem entweder die Zeilen in einer Tabelle durchlaufen oder neue Zeilen in eine Tabelle eingefügt werden können. Cursor können in drei Formen auftreten: als Such-, Einfüge- oder Aktualisierungs-Cursor. Cursor werden im Allgemeinen dazu verwendet, bestehende Geometrie zu lesen und neue Geometrie zu schreiben.

Jeder Cursor-Typ wird durch eine entsprechende ArcPy-Funktion (SearchCursor, InsertCursor oder UpdateCursor) für eine Tabelle, eine Tabellensicht, eine Feature-Class oder einen Feature-Layer erstellt. Mit einem Such-Cursor können Zeilen abgerufen werden. Mit einem Aktualisierungs-Cursor können Zeilen positionsabhängig aktualisiert und gelöscht werden. Mit einem Einfüge-Cursor können Sie Zeilen in eine Tabelle oder Feature-Class einfügen.

CursorErklärung

arcpy.da.InsertCursor(in_table, field_names)

Fügt Zeilen ein.

arcpy.da.SearchCursor(in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause})

Schreibgeschützter Zugriff

arcpy.da.UpdateCursor(in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause})

Aktualisiert oder löscht Zeilen.

Cursor-Funktionen für den Datenzugriff (arcpy.da)
Ältere Versionen:

In ArcGIS 10.1 wurde ein neues Datenzugriffsmodul (arcpy.da) bereitgestellt. Die zuvor vorhandenen Cursor (weiterhin unter arcpy aufgeführt) sind immer noch funktional und gültig. Die neuen arcpy.da-Cursor bieten jedoch eine bedeutend schnellere Performance. In den meisten Fällen wird in der Hilfedokumentation die Verwendung der arcpy.da-Cursor beschrieben. Weitere Informationen zum klassischen Cursormodell finden Sie in der nachfolgenden Tabelle.

CursorErklärung

arcpy.InsertCursor(dataset, {spatial_reference})

Fügt Zeilen ein.

arcpy.SearchCursor(dataset, {where_clause}, {spatial_reference}, {fields}, {sort_fields})

Schreibgeschützter Zugriff

arcpy.UpdateCursor(dataset, {where_clause}, {spatial_reference}, {fields}, {sort_fields})

Aktualisiert oder löscht Zeilen.

Cursorfunktionen (arcpy)
Hinweis:

Cursor berücksichtigen Definitionsabfragen und Auswahlen in Layern und Tabellensichten. Das Cursor-Objekt enthält nur die Zeilen, die von allen Geoverarbeitungswerkzeugen für Operationen verwendet werden.

Cursor können nur in Vorwärtsrichtung durchlaufen werden. Das Zurückkehren zu und Abrufen von bereits abgerufenen Zeilen wird nicht unterstützt. Wenn ein Skript die Daten mehrmals durchlaufen muss, kann die Methode reset aufgerufen werden.

Such- oder Aktualisierungs-Cursor können mit einer for-Schleife durchlaufen werden. Um auf die nächste Zeile zuzugreifen, können Sie auch die next-Methode des Cursors explizit verwenden, um die nächste Zeile zurückzugeben. Wenn Sie die next-Methode eines Cursors verwenden, um alle Zeilen einer Tabelle mit N Zeilen abzurufen, muss das Skript N Aufrufe von next durchführen. Wenn next aufgerufen wird, nachdem die letzte Zeile im Ergebnissatz abgerufen wurde, wird eine StopIteration-Ausnahme zurückgegeben.

import arcpy
cursor = arcpy.da.SearchCursor(fc, ['fieldA', 'fieldB'])
for row in cursor:
    print(row)

Such- und Aktualisierungs-Cursor unterstützen auch with-Anweisungen.

import arcpy
with arcpy.da.SearchCursor(fc, ['fieldA', 'fieldB']) as cursor:
    for row in cursor:
        print(row)

Jede aus einer Tabelle abgerufene Zeile wird als Liste mit Feldwerten zurückgegeben. Die Werte werden in der Reihenfolge zurückgegeben, in der sie im field_names-Argument des Cursors angegeben sind. Mit der fields-Eigenschaft eines Cursors kann auch die Reihenfolge von Feldwerten bestätigt werden.

Cursor-Objekt

Die Funktionen SearchCursor, UpdateCursor und InsertCursor erstellen ein Cursor-Objekt, das zum Durchlaufen der Datensätze verwendet werden kann. Welche Methoden das von den verschiedenen Cursor-Funktionen erstellte Cursor-Objekt aufweist, hängt vom Typ des erstellten Cursors ab.

Im folgenden Diagramm werden die unterstützten Methoden für die einzelnen Cursor-Typen aufgeführt:

Cursor-TypMethodeAuswirkung auf Position

arcpy.da.SearchCursor

reset()

Setzt den Cursor auf die Anfangsposition zurück.

arcpy.da.InsertCursor

insertRow()

Fügt eine Zeile in die Tabelle ein.

arcpy.da.UpdateCursor

updateRow()

Aktualisiert die aktuelle Zeile.

deleteRow()

Entfernt eine Zeile aus der Tabelle.

reset()

Setzt den Cursor auf die Anfangsposition zurück.

insertRow

Ein Einfüge-Cursor wird verwendet, um Zeilen zu erstellen und diese einzufügen. Sobald der Cursor erstellt wurde, wird mit der insertRow-Methode eine Liste (oder ein Tupel) mit Werten eingefügt, die die neue Zeile bilden. Jedem Feld in der Tabelle, das nicht im Cursor enthalten ist, wird der Standardwert des Feldes zugewiesen.

import arcpy
# Create insert cursor for table
cursor = arcpy.da.InsertCursor("c:/base/data.gdb/roads_lut", 
                               ["roadID", "distance"])
# Create 25 new rows. Set the initial row ID and distance values
for i in range(0,25):
    cursor.insertRow([i, 100])

updateRow

Mit der updateRow-Methode kann die Zeile an der aktuellen Position eines Aktualisierungs-Cursors aktualisiert werden. Nachdem eine Zeile aus dem Cursor-Objekt zurückgegeben wurde, können Sie die Zeile wie gewünscht ändern und updateRow aufrufen, um die geänderte Zeile zu übergeben.

import arcpy
# Create update cursor for feature class
with arcpy.da.UpdateCursor("c:/base/data.gdb/roads",
                           ["roadtype", "distance"]) as cursor:
    for row in cursor:
        # Update the values in the distance field by multiplying 
        #   the roadtype by 100. Road type is either 1, 2, 3 or 4.
        row[1] = row[0] * 100
        cursor.updateRow(row)

deleteRow

Mit der deleteRow-Methode kann die Zeile an der aktuellen Position eines Aktualisierungs-Cursors gelöscht werden. Rufen Sie nach dem Abrufen der Zeile deleteRow für den Cursor auf, um die Zeile zu löschen.

import arcpy
# Create update cursor for feature class
with arcpy.da.UpdateCursor("c:/base/data.gdb/roads", 
                          ["roadtype"]) as cursor:
    # Delete all rows that have a roads type of 4
    for row in cursor:
        if row[0] == 4:
            cursor.deleteRow()

Zugreifen auf und Festlegen von Feldwerten

Für jeden Cursor sind die verwendeten Felder in einer Liste (oder einem Tupel) mit Feldnamen angegeben. Eine Zeile wird vom Cursor als Liste mit Feldwerten zurückgegeben, die einer Indexposition entsprechen.

Im nachfolgenden Beispiel erfolgt der Zugriff auf den Bundesstaat und die Bevölkerungsanzahl anhand der Position.

import arcpy
fc = "c:/base/data.gdb/USA/States"
# Use SearchCursor to access state name and the population count
with arcpy.da.SearchCursor(fc, ['STATE_NAME', 'POP2000']) as cursor:
    for row in cursor:
        # Access and print the row values by index position.
        #   state name: row[0]
        #   population: row[1]
        print('{} has a population of {}'.format(row[0], row[1]))
Tipp:

Sie können zwar auf alle Felder mit einem Sternchen (*) zugreifen, das wird im Allgemeinen jedoch nicht empfohlen. Je mehr Felder angegeben sind, desto langsamer ist die Performance des Cursors. Wenn Sie nur die Felder auflisten, die Sie erwartungsgemäß verwenden werden, wird die Gesamteffizienz des Cursors verbessert.

Token können auch als Verknüpfungen anstelle der Feldnamen verwendet werden. Alle Tabellen enthalten ein ObjectID-Feld, das abhängig vom Datentyp unterschiedliche Namen haben kann. Für Simple-Feature-Classes ist ein Geometriefeld erforderlich, in der Regel (aber nicht immer) Shape genannt. Der OID@-Token kann verwendet werden, um auf das ObjectID-Feld zuzugreifen, und der SHAPE@-Token (der ein Geometrieobjekt zurückgibt) kann verwendet werden, um auf das Geometriefeld einer Feature-Class zuzugreifen, wobei die Feldnamen vorab nicht bekannt sein müssen.

Such-Cursor für Multipoint-Feature-Class
import arcpy
infc = arcpy.GetParameterAsText(0)
# Enter for loop for each feature
for row in arcpy.da.SearchCursor(infc, ["OID@", "SHAPE@"]):
    # Print the current multipoint's ID
    print("Feature {}:".format(row[0]))
    # For each point in the multipoint feature,
    #  print the x,y coordinates
    for pnt in row[1]:
        print("{}, {}".format(pnt.X, pnt.Y))

Zusätzliche Geometrie-Token können verwendet werden, um auf bestimmte Geometrieinformationen zuzugreifen. Der Zugriff auf die gesamte Geometrie nimmt mehr Zeit in Anspruch. Wenn Sie nur bestimmte Eigenschaften der Geometrie benötigen, stellen Sie mithilfe von Token Verknüpfungen bereit, um auf Geometrieeigenschaften zuzugreifen. Zum Beispiel gibt SHAPE@XY ein Tupel von XY-Koordinaten zurück, die den Schwerpunkt des Features darstellen.

Cursor und Sperren

Einfüge- und Aktualisierungs-Cursor berücksichtigen Tabellensperren, die von ArcGIS-Anwendungen festgelegt werden. Sperren verhindern, dass eine Tabelle zu einem bestimmten Zeitpunkt von mehreren Prozessen gleichzeitig geändert wird. Es gibt zwei Typen von Sperren: freigegebene Sperren und exklusive Sperren. Sie werden im Folgenden beschrieben.

  • Eine freigegebene Sperre wird bei jedem Zugriff auf eine Tabelle oder ein Dataset gesetzt. Für eine Tabelle können mehrere freigegebene Sperren vorliegen. Wenn eine freigegebene Sperre vorliegt, sind jedoch keine exklusiven Sperren zulässig. Das Anzeigen einer Feature-Class und die Vorschau einer Tabelle sind Beispiele für Situationen, in denen eine freigegebene Sperre gesetzt wird.
  • Exklusive Sperren werden gesetzt, wenn Änderungen an einer Tabelle oder Feature-Class vorgenommen werden. Das Bearbeiten und Speichern einer Feature-Class in einer Karte, das Ändern eines Tabellenschemas oder das Verwenden eines Einfüge-Cursors für eine Feature-Class in einer Python-IDE sind Beispiele für Situationen, in denen von ArcGIS eine exklusive Sperre gesetzt wird.

Aktualisierungs- und Einfüge-Cursor können für eine Tabelle oder eine Feature-Class nur erstellt werden, wenn für das betreffende Dataset keine exklusive Sperre vorliegt. Die Funktion UpdateCursor oder InsertCursor schlägt aufgrund einer exklusiven Sperre des Datasets fehl. Wenn mit diesen Funktionen erfolgreich ein Cursor erstellt wird, wird eine exklusive Sperre für das Dataset festgesetzt, sodass immer nur ein Skript Aktualisierungs- oder Einfüge-Cursor für dasselbe Dataset erstellen kann.

In Python bleibt die Sperre erhalten, bis der Cursor freigegeben wird. Andernfalls werden alle anderen Anwendungen und Skripte unnötigerweise am Zugriff auf das betreffende Dataset gehindert. Ein Cursor kann wie folgt freigegeben werden:

  • Durch Verwenden des Cursors in einer with-Anweisung, die die Aufhebung von Sperren unabhängig davon garantiert, ob der Cursor erfolgreich abgeschlossen wird
  • Durch Aufrufen von reset für den Cursor
  • Der Cursor wurde erfolgreich abgeschlossen.
  • Löschen Sie explizit den Cursor mit der del-Anweisung von Python.

In einer Editiersitzung wird eine freigegebene Sperre für Daten gesetzt. Beim Speichern der Änderungen wird eine exklusive Sperre gesetzt. Ein Dataset kann nicht bearbeitet werden, wenn bereits eine exklusive Sperre vorliegt.

Cursor und BLOB-Felder

Bei einem BLOB (Binary Large Object) handelt es sich um Daten, die als lange Abfolge von binären Zahlen gespeichert sind. In ArcGIS werden Annotation und Bemaßungen als BLOBs gespeichert. In Feldern dieses Typs können auch Objekte wie Bilder, Multimedia-Komponenten oder Programmcode gespeichert werden. Sie können einen Cursor verwenden, um den Inhalt eines BLOB-Feldes zu laden oder anzuzeigen.

In Python können in BLOB-Feldern Zeichenfolgen, bytearray und memoryviews eingegeben werden. Beim Lesen von BLOB-Feldern wird ein memoryview-Objekt zurückgegeben.

import arcpy
data = open("c:/images/image1.png", "rb").read()
ic = arcpy.da.InsertCursor("c:/data/fgdb.gdb/fc", ['imageblob'])
ic.insertRow([data])
import arcpy sc = arcpy.da.SearchCursor("c:/data/fgdb.gdb/fc", ["imageblob"]) memview = sc.next()[0] open("c:/images/image1_copy.png", "wb").write(memview.tobytes())