5 votos

Uso correcto de un contador con arcpy.da.UpdateCursor

En el código de Python dentro de una Calculate Value herramienta en mi modelo, tengo lo siguiente:

getNum("%Selected Features%")

def getNum(ftr):
  lst = [4, 11, 15] #values for SQL expression
  x = 20
  fields = ('TYPE_A', 'TYPE_B', 'NUM_ID')
  for l in lst:
    y = x + 1
    whereclause = """"NUM_ID" = %s """ % l
    with arcpy.da.UpdateCursor(ftr, fields, whereclause) as cursor:
      for row in cursor:
        if row[0] ! = row[1]:
          row[2] = y
        cursor.updateRow(row)
    y += 1

Lo que me gustaría hacer es, para cada elemento de la lst, crear un cursor basado en una selección de registros donde NUM_ID = l. Los valores en TYPE_A y TYPE_B deben ser comparados para cada registro y actualiza si es necesario.

El guión está fallando después de que el cursor se crea, con el error Item not in collection. Si puedo quitar el whereclause, que se ejecuta. Una vez que los registros han sido seleccionados y los valores de comparación y se actualiza si es necesario, tengo que incrementar el contador y por 1. Creo que me estoy haciendo en el lugar equivocado, porque si ejecuto el script sin la whereclause no se ejecutarán correctamente.Cuando reviso los registros con los valores cambiados, ahora están todos a y, lo que indica que y fue no se incrementa.

5voto

ESV Puntos 4591

Par de puntos que podrían ayudar:

  • Redefinir el valor de y al principio del bucle, así que cada vez que se ejecuta el bucle y es restablecer x + 1. En lugar de establecer y fuera del bucle:
y = x + 1
for l in lst:
    #...
  • Dependiendo del tipo de clase de entidad de que usted está utilizando ArcGIS requiere delimitadores diferentes alrededor de nombres de campo. Por ejemplo, [PERSONAL_GDB] vs "FILE_GDB". Para evitar tener que preocuparse acerca de esto, usted puede usar la AddFieldDelimiters de arcpy función para obtener los delimitado correctamente los campos.
#Using dictionary string-formatting
whereclause = "%(sql_name)s = %(l)i """ % {"sql_name":arcpy.AddFieldDelimiters(ftr, "NUM_ID"), "l":l}
  • Por último, usted probablemente debería comprobar que NUM_ID existe en la clase de entidad de lo contrario, el cursor se va a caer. Usted puede utilizar ListFields de este.
assert "NUM_ID" in [f.name for f in arcpy.ListFields(ftr)], "NUM_ID field no in feature class"

3voto

auramo Puntos 161

Además de sugerencias de gran @om_henners, me parece que como se puede utilizar un IN declaración para reducir el número de consultas a la base de datos de len(lst) a 1. Tengo una función de ejemplo para construir tal una cláusula WHERE en esta respuesta: seleccionar funciones de atributo si en la lista de Python

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X