Establecer parámetros en la herramienta de script usando Python?


8

Odio molestarlos a todos con el mismo problema una y otra vez, pero me encuentro con un nuevo problema cada vez que hago un ligero cambio en el código. Todo lo que hice con el siguiente código fue reemplazar los nombres de campo para que coincidan con la clase de entidad original. Ahora no funciona. Me dio

<type 'exceptions.RuntimeError'>: ERROR 999999: Error executing function. Failed to execute (Script).

Intenté agregar Try / Except al código que no me dio ningún mensaje de error pero tampoco me dio ningún resultado.

No estoy seguro de lo que está pasando? Cualquier ayuda para resolver esto será muy apreciada.

import arcpy, os
Try:
roadpath = arcpy.GetParameterAsText(0)
tablepath = arcpy.GetParameterAsText(1)

datapath = os.path.split(tablepath)[0]
tablename = os.path.split(tablepath)[1]
rows = arcpy.SearchCursor(roadpath,"FROMLEFT <> 0 AND TOLEFT <> 0","","STREET_NAME_ID;FROMLEFT;TOLEFT","STREET_NAME_ID A;FROMLEFT A;TOLEFT A")
arcpy.env.workspace = datapath

if arcpy.Exists(tablename):
    arcpy.DeleteRows_management(tablename)
else:
    arcpy.CreateTable_management(datapath,tablename,roadpath)
    arcpy.DeleteField_management(tablename,"SHAPE_Length")

irows = arcpy.InsertCursor(tablename)
first = True
for row in rows:
    if first:
        first = False
    else:
        GISID = row.GIS_ID
        stid = row.STREET_NAME_ID
        fl = row.FROMLEFT
        tl = row.TOLEFT
        if stid == prev_stid and fl <= prev_tl:
            irow = irows.newRow()
            irow.GIS_ID = prev_GISID
            irow.STREET_NAME_ID = prev_stid
            irow.FROMLEFT = prev_fl
            irow.TOLEFT = prev_tl
            irows.insertRow(irow)
            del irow
            irow = irows.newRow()
            irow.GIS_ID = GISID
            irow.STREET_NAME_ID = stid
            irow.FROMLEFT = fl
            irow.TOLEFT = tl
            irows.insertRow(irow)
            del irow
    prev_GISID = row.GIS_ID
    prev_stid = row.STREET_NAME_ID
    prev_fl = row.FROMLEFT
    prev_tl = row.TOLEFT
del rows, irows
except:
print arcpy.GetMessages()

Hola Sam, bienvenido a GIS.se :) ver si poniendo Everthing partir rows =de irowsincluido en un bloque try ... except da un mensaje de error más revelador. También sería útil si puede poner una muestra de los datos y el script completo en alguna parte ( minus.com es un lugar para compartir fácilmente con el público).
Matt Wilkie

Arreglé el formato del código en su Q. Parte del mensaje de error estaba siendo comido por los corchetes angulares. Para su información, presione [ctrl] - [K] cuando esté en modo de edición para aplicar automáticamente el formato de código al texto seleccionado. Un bloque tiene sangría en cuatro espacios y un código en línea con ` `
marcas en la

Con respecto a su última edición, parece que la variable definida en la segunda línea debería leer en tablepathlugar de tablename. ¿Es solo un error tipográfico en el foro o es realmente así en el script? El error sugiere lo primero, entonces, ¿puede proporcionar ejemplos de los valores que está pasando a ambos parámetros? ¿También tienes una import arcpylínea en la parte superior de tu script?
blah238

No hay forma de que podamos depurar esto por usted: tome PyScripter u otro IDE de Python y comience a depurar. Al contrario de lo que dijo Matt, si eliminas el try / except, deberías obtener un seguimiento completo de la pila cuando el programa bombardea, con suerte llevándote a la línea en la que está el error. También podría escribir explícitamente el seguimiento de la pila utilizando el módulo de rastreo, pero probablemente más trabajo que simplemente eliminar el try / except. Ver también: blogs.esri.com/Dev/blogs/geoprocessing/archive/2008/12/01/… 2D00 -Error-handling-in-Python-script-tools.aspx
blah238

El problema era la longitud del nombre del campo. Aparentemente, a python no le gustan los nombres largos de campo (> 10 caracteres). Parece estar funcionando ahora. Voy a probar algo nuevo mañana y estoy seguro de que tendré nuevos problemas. Pero gracias por tus sugerencias. Necesito aprender a depurar el script de Python. ¿Conoces algún recurso?
Sam

Respuestas:


4

Los parámetros que ha configurado actualmente no deberían ser parámetros de "salida", ya que son argumentos de cadena simples para sus métodos de geoprocesamiento, no salidas verdaderas.

Hay dos formas de hacerlo:

  1. Reemplace sus dos parámetros de "Ubicación de salida" y "Tabla de salida" con un único parámetro de salida de tipo Tabla para proporcionar la ruta completa a la tabla de salida, y actualice su lógica de script para analizar este parámetro en los componentes de ruta necesarios utilizando os.path.splitsegún sea necesario para funciones de geoprocesamiento que está utilizando.
  2. Cambie los parámetros de "Ubicación de salida" y "Tabla de salida" para que sean parámetros de entrada (también cambiaría el nombre de "Tabla de salida" a "Nombre de tabla de salida" para aclarar que es solo el nombre de la tabla, no la ruta completa). Cree un nuevo cuarto parámetro de tipo Derivado y modifique la ToolValidatorclase de su herramienta de script para establecer su valor después de que los parámetros 2 y 3 hayan sido validados.

El primer método es probablemente el camino más fácil: la lógica de ToolValidator es difícil de corregir y difícil de depurar.

EDITAR: en realidad, hay una tercera opción que puede funcionar para sus propósitos: es lo mismo que el método dos, pero en lugar de modificar ToolValidator, llame SetParameterAsTextal final de su script para establecer el valor del cuarto parámetro derivado. He tenido problemas con SetParameterAsText en el pasado en las herramientas de secuencia de comandos utilizadas en ModelBuilder, pero ahora podría solucionarse.


2

También me gustaría comentar todo el código e imprimir los valores de los parámetros que está pasando. Siempre es bueno poner un poco de depuración.

También es una buena práctica verificar los parámetros a medida que entran:

# First parameter is ID
ID = long(arcpy.GetParameterAsText(0))

# parameter is optional feature class prefix 
appPrefix = arcpy.GetParameterAsText(1)
if (not appPrefix) or (appPrefix == "#") or (len(appPrefix.strip()) == 0):
    appPrefix = ""

# Optional schema owner
schemaOwner = arcpy.GetParameterAsText(2)
if (not schemaOwner) or (schemaOwner == "#") or (len(schemaOwner.strip()) == 0):
    schemaOwner = ""
else:
    schemaOwner = schemaOwner + "."

# Optional workspace - for use with ArcGIS Desktop. No default.
workspace = arcpy.GetParameterAsText(3)
if (not workspace) or (workspace == "#") or (len(workspace.strip()) == 0):
    workspace = os.path.join(sys.path[0], connFile)

Algo así, luego asegúrese de imprimir las variables para poder verlas:

arcpy.AddMessage("ID : " + str(Id))

o

print "ID : " + str(Id)

Etc. Debe saber que los valores que entran no son basura, ya que siempre estará persiguiendo su cola.

Poner la fila / cur en un intento de captura también es una buena práctica.


0

Estoy de acuerdo con bla, la dirección de todos sus parámetros debe ser "entrada". Además, está especificando el tipo de datos del parámetro de herramienta 3, la tabla de salida, como un objeto de archivo; intente esto como una "tabla" o "cadena".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.