Definindo parâmetros na ferramenta de script usando Python?

8

Eu odeio incomodar todos vocês com o mesmo problema repetidamente, mas encontro um novo problema sempre que faço uma pequena alteração no código. Tudo o que fiz no código abaixo foi substituir os nomes dos campos para corresponder à classe do recurso original. Agora não funciona. Deu-me

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

Tentei adicionar Try / Except ao código que não me deu nenhuma mensagem de erro, mas também não deu nenhum resultado.

Não tenho certeza do que está acontecendo? Qualquer ajuda para descobrir isso será muito 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()
Sam
fonte
Oi Sam, bem-vindo ao GIS.se :) ver se colocar Everthing de rows =que irowsinclusive em um try ... exceto bloco dá uma mensagem de erro mais revelador. Também ajudaria se você pudesse colocar uma amostra dos dados e do script completo em algum lugar ( minus.com é um local para fácil compartilhamento público).
214118 #
Corrigi a formatação do código no seu Q. Parte da mensagem de erro estava sendo comida pelos colchetes angulares. Para sua informação, pressione [ctrl] - [K] quando estiver no modo de edição para aplicar automaticamente a formatação do código ao texto selecionado. Um bloco é indentado com quatro espaços, eo código em linha com volta carrapatos: ` ` (ref)
Matt Wilkie
Em relação à sua edição mais recente, parece que a variável definida na segunda linha deve ler em tablepathvez de tablename. Isso é apenas um erro de digitação no fórum ou é realmente assim no script? O erro sugere o primeiro, então você pode fornecer exemplos dos valores que está passando para os dois parâmetros? Você também tem uma import arcpylinha na parte superior do seu script?
blah238
Não há como depurar isso para você - pegue o PyScripter ou outro IDE do Python e comece a depurar. Ao contrário do que matt disse, se você remover a tentativa / exceção, deverá obter um rastreamento completo da pilha quando o programa bombardear, com sorte levando você à linha em que o erro está. Você também pode escrever explicitamente o rastreamento de pilha usando o módulo traceback, mas provavelmente mais trabalho do que apenas remover a tentativa / exceção. Veja também: blogs.esri.com/Dev/blogs/geoprocessing/archive/2008/12/01/... 2D00 -Erro de manipulação-in-Python-script-tools.aspx
blah238
O problema foi o tamanho do nome do campo. Aparentemente, python não gosta de nomes longos de campos (> 10 caracteres). Parece estar funcionando agora. Vou tentar algo novo amanhã e tenho certeza de que vou encontrar um novo conjunto de problemas. Mas obrigado por suas sugestões. Eu preciso aprender a depurar scripts python. Você conhece algum recurso?
Sam

Respostas:

4

Os parâmetros que você configurou atualmente não devem ser parâmetros de "saída", pois são argumentos simples de seqüência de caracteres para seus métodos de geoprocessamento, não saídas verdadeiras.

Há duas maneiras de fazer isso:

  1. Substitua seus dois parâmetros "Local de Saída" e "Tabela de Saída" por um único parâmetro de saída do tipo Tabela para fornecer o caminho completo para a tabela de saída e atualize sua lógica de script para analisar esse parâmetro nos componentes de caminho necessários, os.path.splitconforme necessário para o funções de geoprocessamento que você está usando.
  2. Altere os parâmetros "Local de saída" e "Tabela de saída" para serem parâmetros de entrada (eu também renomeio "Tabela de saída" para "Nome da tabela de saída" para esclarecer que é apenas o nome da tabela, não o caminho completo para ela). Crie um novo quarto parâmetro do tipo Derivado e modifique a ToolValidatorclasse da sua ferramenta de script para definir seu valor após a validação dos parâmetros 2 e 3.

O primeiro método é provavelmente o caminho mais fácil - a lógica do ToolValidator é complicada de acertar e difícil de depurar.

EDIT: Na verdade, existe uma terceira opção que pode funcionar para seus propósitos - é o mesmo que o método dois, mas em vez de modificar o ToolValidator, chame SetParameterAsTextno final do seu script para definir o valor do quarto parâmetro derivado. Eu tive problemas com o SetParameterAsText no passado nas ferramentas de script usadas no ModelBuilder, mas ele pode ser corrigido agora.

blah238
fonte
2

Eu também gostaria de comentar todo o código e imprimir os valores dos parâmetros que você está passando. Sempre bom colocar um pouco de depuração.

Também é uma boa prática verificar os parâmetros quando eles entram:

# 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 assim, certifique-se de imprimir as variáveis ​​para poder vê-las:

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

ou

print "ID : " + str(Id)

Etc. Você precisa saber que os valores inseridos não são lixo, pois sempre estará perseguindo sua cauda.

Colocar a linha / curva em uma captura de tentativa também é uma boa prática.

Peludo
fonte
0

Eu concordo com blá, a direção de todos os seus parâmetros deve ser "entrada". Além disso, você está especificando o tipo de dados do parâmetro 3 da ferramenta, a tabela de saída, como um objeto de arquivo; tente isso como uma "tabela" ou "string".

Jason
fonte