¿Eliminar entidades de clase de entidad más rápido con ArcPy?

8

He escrito este script que se repite a través de todas las clases de entidades en un conjunto dado de conjuntos de datos de entidades y elimina todas sus funciones. Parece que hace el trabajo pero funciona bastante lento. ¿Hay algo que estoy haciendo mal aquí o hay formas obvias de acelerar las cosas?

Estoy usando DeleteFeatures_management para hacer la escritura. DeleteRows_management también parece funcionar.

import sys
import os
import arcpy
from arcpy import env
import datetime
import getpass

try:
    passwd = getpass.getpass("Enter the sde user password: ")

    sdeConnectionFileDir = os.environ.get("TEMP")
    databaseName = ""
    fileName = "temp.sde"

    # Delete any pre-existing SDE connection file.
    fullPath = sdeConnectionFileDir + '\\' + fileName
    if os.path.exists(fullPath):
        os.remove(fullPath)

    # Create temporary SDE connection file.
    arcpy.CreateArcSDEConnectionFile_management (
        sdeConnectionFileDir, fileName,
        "sdeserver", "5151", "",
        "DATABASE_AUTH", "my_sde_user", passwd,
        "SAVE_USERNAME", "SDE.DEFAULT", "SAVE_VERSION"
    )

    env.workspace = fullPath

    # ArcPy status codes.
    returnCodes = {'WARN' : 0, 'INFO' : 1, 'ERROR' : 2}

    featureDatasets = []
    featureDatasets.extend(arcpy.ListDatasets("dataset1*"))
    featureDatasets.extend(arcpy.ListDatasets("dataset2*"))
    featureDatasets.extend(arcpy.ListDatasets("dataset3*"))

    list = '[%s]' % ', '.join(map(str, featureDatasets))
    response = raw_input("\n***** WARNING!!! ***** \nAll data will be deleted from all feature classess in the following datasets: \n\n" + list + "\n\n |--> Type DELETE to begin removal: ")
    if response == "DELETE":
        print "\nStarted: " + str(datetime.datetime.now()) + "\n"
        for dataset in featureDatasets:
            print "Processing dataset: " + dataset
            for fc in arcpy.ListFeatureClasses("*", "ALL", dataset):
                rowCount = int(arcpy.GetCount_management(fc).getOutput(0))

                if rowCount > 0:
                    print "  -- Processing feature class: " + str(fc) + " (" + str(rowCount) + " rows)"
                    #arcpy.DeleteRows_management(fc)
                    arcpy.DeleteFeatures_management(fc)

        print "\nCompleted: " + str(datetime.datetime.now())

except Exception as e:
    if arcpy:
        arcpyErrors = arcpy.gp.getMessages(returnCodes['ERROR'])
        if arcpyErrors:
            sys.stderr.write(arcpyErrors + "\n")
    sys.stderr.write(str(e) + "\n")
    sys.exit(1)

EDITAR -

Puse algunos temporizadores de rendimiento en el script y aquí están los datos:

  • Tiempo para recuperar conjuntos de datos: 0: 00: 01.254000
  • Clases de características totales: 1682
  • Total de clases de entidad con datos: 124
  • Total de características procesadas: 190222
  • Tiempo total de ejecución : 3 horas, 16 minutos

La caida:

Conjunto de datos de entidad -> lista de llamadas de clase de entidad:

* AVG   0:00:02
* MIN   0:00:01
* MAX   0:00:07
* COUNT 40
* TOTAL 0:01:08

Llamadas de recuento de funciones (la mayoría de las veces):

* AVG   0:00:06
* MIN   0:00:01
* MAX   0:00:16
* COUNT 1682
* TOTAL 2:41:00

Llamadas de eliminación de funciones (reducidas porque solo se procesan las clases de entidades con filas):

* AVG   0:00:17
* MIN   0:00:02
* MAX   0:03:22
* COUNT 124
* TOTAL 0:34:31
Andy Arismendi
fuente

Respuestas:

14

¿Qué parte del guión realmente ocupa la mayor parte del tiempo? Hay otros 5 pasos antes de comenzar a eliminar cosas.

Es posible que desee dividir su script en pruebas del tamaño de un bocado. Por ejemplo, en lugar de crear un archivo de conexión temporal, enumerar un conjunto de conjuntos de datos, enumerar sus contenidos, contar sus registros y, finalmente, hacer lo que desea hacer (eliminar características), simplemente pase una sola clase de entidad con un prefabricado archivo de conexión a DeleteFeatures y vea cuánto tiempo lleva eso.

Si eso funciona de manera aceptable, cree otra prueba para cronometrar el siguiente punto potencial de problema: contar filas. Y otra para enumerar clases de entidades dentro de un conjunto de datos de entidades, y otra más para enumerar conjuntos de datos de entidades dentro de una geodatabase.

Si, por otro lado, DeleteFeatures no funciona de manera aceptable, entonces al menos sabemos dónde está el problema. En ese caso, estaría más inclinado a ver cómo está diseñada su geodatabase:

  • ¿Alguno de sus conjuntos de datos de funciones está versionado? Cuando se utiliza el control de versiones, existe un par adicional de tablas A (agrega) y D (elimina) para cada tabla versionada, y cuando elimina características que no está eliminando registros en la tabla base, está agregando registros a la tabla D. Esto llevará mucho más tiempo que si no fuera versionado.

  • Dado que todas sus clases de entidad parecen estar en conjuntos de datos de entidades, ¿participan en el comportamiento de la geodatabase, como una topología o una red geométrica? Cuando agrega / elimina / modifica características que participan en el comportamiento de la geodatabase, hay muchos más gastos generales.

  • También tenga en cuenta que, contrariamente a la creencia popular, los conjuntos de datos de características no están diseñados para usarse como una herramienta organizativa:

    Existen conjuntos de datos de entidades en la geodatabase para definir un alcance para una referencia espacial. Todas las clases de entidad que participan en relaciones topológicas entre sí (por ejemplo, una red geométrica) deben tener la misma referencia espacial. Los conjuntos de datos de entidades son una forma de agrupar clases de entidades con la misma referencia espacial para que puedan participar en relaciones topológicas entre sí.

    Para la mayoría de los usuarios, los conjuntos de datos de características también tienen una calidad organizativa natural, muy similar a una carpeta en un sistema de archivos. Dado que para muchas aplicaciones SIG, la mayoría de los datos tienen la misma referencia espacial, la tentación de agrupar grandes cantidades de clases de entidades en conjuntos de datos de entidades es irresistible.

    Sin embargo, los conjuntos de datos de características no son gratuitos. Cuando abre una clase de entidad contenida en un conjunto de datos de entidad para ver sus propiedades o dibujarla o consultarla en ArcCatalog ™, ArcMap ™ o una aplicación personalizada, también se abren todas las otras clases de entidad en ese conjunto de datos de entidad. Esto se hace porque las actualizaciones de una clase de entidad en un conjunto de datos de entidad pueden potencialmente expandirse a otras clases de entidad en el conjunto de datos de entidad que participan en relaciones topológicas.

    De: Sistemas de información geográfica multiusuario con ArcInfo 8 (abril de 2000)

    Por lo tanto, podría ser otra fuente de sobrecarga, incluso si no participan en una topología o red geométrica.

Más allá de los comandos arcpy DeleteFeatures / DeleteRows:

  • Si tiene acceso al comando de administración SDE , puede usar:

    sdetable -o truncate -t <tablename>

    Esto emite comandos de tabla truncada a su DBMS, por lo que debería ser mucho más rápido, pero tenga en cuenta que esto ignora el comportamiento de la geodatabase.

  • Usando ArcSDESQLExecute para emitir TRUNCATE TABLEcomandos directamente (sin pasar por alto el comportamiento de la geodatabase), pero esto es muy propenso a problemas ya que necesitaría emitir uno para cada tabla que conforma una clase de entidad (base, F, S, I, A, D, etc. .) No hacer esto con cuidado y correctamente podría dejar sus datos en un estado inconsistente.

blah238
fuente
Este es un gran consejo. Pondré algunos temporizadores para cada operación y publicaré los resultados. Al menos de los comentarios hasta ahora parece que estoy usando los métodos API de ArcPy apropiados. Todavía estoy aprendiendo la API de ArcPy, así que me preocupaba que hubiera algún otro método que debería usar.
Andy Arismendi
En lo que respecta a arcpy, creo que DeleteRows y DeleteFeatures son lo mejor que puedes hacer, pero agregué algunas otras opciones que vale la pena considerar al menos si esto es crítico.
blah238
Agregué algunas métricas de rendimiento arriba. Hay 1682 clases de entidad. Aunque en promedio el recuento solo tomó 1/3 del tiempo de eliminación. Concedidas, las operaciones de eliminación solo procesaron clases de entidad con entidades. Intentaré eliminar el conteo y simplemente pasar todas las clases de entidad a DeleteRows_management y veré cómo funciona. También intentaré sdetable usando la opción truncar.
Andy Arismendi
2
¡Ay, 1682 clases de características ?! Definitivamente buscaría un flujo de trabajo alternativo para manejar esa cantidad de datos. Cuando comience a hablar de cientos de tablas, realmente debería estar en el back-end trabajando con el DBMS directamente IMO. Haga que sus DBA cocinen algo en PL / SQL o algo :)
blah238
Solo 124 clases de entidad realmente tenían entidades, el resto estaban vacías. Por cierto, me acabas de dar una idea! Quizás crear el archivo de conexión SDE utilizando una conexión directa de Oracle ayudará a mejorar el rendimiento. Lo intentaré a continuación.
Andy Arismendi
9

Si actualizar a ArcGIS 10.1 (ahora lanzado) es una opción, acabo de encontrar esto en el PDF de Novedades de ArcGIS 10.1:

Nueva herramienta para eliminar todas las filas de una tabla

La herramienta de geoprocesamiento TruncateTable en el conjunto de herramientas Tablas se puede usar para eliminar todas las filas de una tabla o clase de entidad. Debe usar la herramienta Truncar tabla en lugar de la herramienta Eliminar filas cuando desee eliminar todas las filas de una tabla o clase de entidad.

Su ayuda en línea se puede encontrar aquí .

PolyGeo
fuente
1
Esto es mucho más rápido que DeleteRows
nmpeterson el
3
Lo único es que no admite tablas versionadas / clases de entidad.
Ruchira Welikala
5

¿Por qué no simplemente eliminar los datasets de características con ellos mismos arcpy.DeleteFeatures_management(dataset)? Si aún necesita que exista el dataset de características, simplemente puede volver a crearlo después de que se haya eliminado.

nmpeterson
fuente
Necesito mantener los conjuntos de datos de características y sus clases de características alrededor porque no se vuelven a crear rápidamente debido a la combinación SDE / Oracle y hay bastantes clases de características. Estoy tratando de eliminar las funciones lo más rápido posible.
Andy Arismendi