9 votos

¿Cómo copiar una geodatabase SDE a una geodatabase de archivos usando Python?

Me gustaría hacer una copia exacta (dominios, característica de los conjuntos de datos, las clases de entidad, etc.) de un SDE base de datos en una geodatabase de archivos.

He intentado varias posibilidades, incluyendo:

  1. el uso de la Copia (Gestión de Datos) proceso de
  2. la creación de un nuevo GDB y copia manual de cada una de las características del conjunto de datos de la SDE
  3. la exportación de un documento de espacio de trabajo xml de la SDE y la importación en el GDB

El Copy_management proceso no parece como sería el trabajo para copiar un SDE a un GDB, puesto que la entrada y salida de los tipos de datos deben coincidir.

El proceso de importación de cada una de las características del conjunto de datos en un nuevo GDB probablemente podría ser automatizado mediante Copy_management así por iteración a través de cada una de las características del conjunto de datos, aunque parece que esto podría causar problemas de una copia incompleta si hubo un error con uno de los procesos.

Exportación e importación de xml áreas de trabajo se parece al trabajo, a pesar de que este proceso crea increíblemente archivos de gran tamaño cuando el proceso se utiliza en grandes bases de datos geográficas.

Hay una forma más sencilla y directa para copiar el contenido y el esquema de una SDE un GDB de las formas mencionadas, en una forma que puede ser automatizado?

Si no, ¿hay razones que las anteriores posibilidades no deben ser utilizados en este proceso?

8voto

jomey Puntos 302

Sé que este post es un poco viejo, pero yo, sin embargo, me gustaría compartir mi respuesta, ya que me encontraba con el mismo problema. La siguiente secuencia de comandos DEBE hacer una copia de todas las tablas y clases de entidad de relaciones, no en un conjunto de datos y también va a copiar todos los conjuntos de datos, incluyendo las clases de entidad, topología, etc dentro del conjunto de datos. Se omitirá cualquier error durring la copia del adn de seguir adelante. Esto creará un archivo de registro que contiene datos como el origen de DB número de elementos y el elemento de destino recuento de lo que se puede comparar la copia y va a errores de registro que se encuentra así.

import arcpy, os, shutil, time
import logging as log
from datetime import datetime

def formatTime(x):
    minutes, seconds_rem = divmod(x, 60)
    if minutes >= 60:
        hours, minutes_rem = divmod(minutes, 60)
        return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
    else:
        minutes, seconds_rem = divmod(x, 60)
        return "00:%02d:%02d" % (minutes, seconds_rem)

def getDatabaseItemCount(workspace):
    arcpy.env.workspace = workspace
    feature_classes = []
    for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,datatype="Any",type="Any"):
        for filename in filenames:
            feature_classes.append(os.path.join(dirpath, filename))
    return feature_classes, len(feature_classes)

def replicateDatabase(dbConnection, targetGDB):
    startTime = time.time()

    featSDE,cntSDE = getDatabaseItemCount(dbConnection)
    featGDB,cntGDB = getDatabaseItemCount(targetGDB)

    now = datetime.now()
    logName = now.strftime("SDE_REPLICATE_SCRIPT_%Y-%m-%d_%H-%M-%S.log")
    log.basicConfig(datefmt='%m/%d/%Y %I:%M:%S %p', format='%(asctime)s %(message)s',\
    filename=logName,level=log.INFO)

    print "Old Target Geodatabase: %s -- Feature Count: %s" %(targetGDB, cntGDB)
    log.info("Old Target Geodatabase: %s -- Feature Count: %s" %(targetGDB, cntGDB))
    print "Geodatabase being copied: %s -- Feature Count: %s" %(dbConnection, cntSDE)
    log.info("Geodatabase being copied: %s -- Feature Count: %s" %(dbConnection, cntSDE))

    arcpy.env.workspace = dbConnection

    #deletes old targetGDB
    try:
        shutil.rmtree(targetGDB)
        print "Deleted Old %s" %(os.path.split(targetGDB)[-1])
        log.info("Deleted Old %s" %(os.path.split(targetGDB)[-1]))
    except Exception as e:
        print e
        log.info(e)

    #creates a new targetGDB
    GDB_Path, GDB_Name = os.path.split(targetGDB)
    print "Now Creating New %s" %(GDB_Name)
    log.info("Now Creating New %s" %(GDB_Name))
    arcpy.CreateFileGDB_management(GDB_Path, GDB_Name)

    datasetList = [arcpy.Describe(a).name for a in arcpy.ListDatasets()]
    featureClasses = [arcpy.Describe(a).name for a in arcpy.ListFeatureClasses()]
    tables = [arcpy.Describe(a).name for a in arcpy.ListTables()]

    #Compiles a list of the previous three lists to iterate over
    allDbData = datasetList + featureClasses + tables

    for sourcePath in allDbData:
        targetName = sourcePath.split('.')[-1]
        targetPath = os.path.join(targetGDB, targetName)
        if arcpy.Exists(targetPath)==False:
            try:
                print "Atempting to Copy %s to %s" %(targetName, targetPath)
                log.info("Atempting to Copy %s to %s" %(targetName, targetPath))
                arcpy.Copy_management(sourcePath, targetPath)
                print "Finished copying %s to %s" %(targetName, targetPath)
                log.info("Finished copying %s to %s" %(targetName, targetPath))
            except Exception as e:
                print "Unable to copy %s to %s" %(targetName, targetPath)
                print e
                log.info("Unable to copy %s to %s" %(targetName, targetPath))
                log.info(e)
        else:
            print "%s already exists....skipping....." %(targetName)
            log.info("%s already exists....skipping....." %(targetName))
    featGDB,cntGDB = getDatabaseItemCount(targetGDB)
    print "Completed replication of %s -- Feature Count: %s" %(dbConnection, cntGDB)
    log.info("Completed replication of %s -- Feature Count: %s" %(dbConnection, cntGDB))
    totalTime = (time.time() - startTime)
    totalTime = formatTime(totalTime)
    log.info("Script Run Time: %s" %(totalTime))

if __name__== "__main__":
    databaseConnection = r"YOUR_SDE_CONNECTION"
    targetGDB = "DESTINATION_PATH\\SDE_Replicated.gdb"
    replicateDatabase(databaseConnection, targetGDB)   

He tenido muy buena suerte con este. Yo era replicar una base de datos SDE a una geodatabase de archivos. Yo no he hecho demasiado extensa de pruebas en esta secuencia de comandos a pesar de que ya cumplió con todas mis necesidades. He probado usando ArcGIS 10.3. También, una cosa a tener en cuenta, yo estaba en conversaciones con alguien que ha utilizado este script y se toparon con un problema con un error en la copia de algunos de los conjuntos de datos debido a un inadecuado de los permisos y de las mesas vacías.

Lemur - ¿por qué no crear sus relaciones en base a un global de identificación en lugar del id de objeto? Que tus relaciones sean preservados. Si aún no has creado global de identificación del yo se lo recomiendo.

-actualización

He añadido un poco más de lógica en el código para controlar el mal de la base de datos de las rutas de conexión y un mejor registro y control de errores:

import time, os, datetime, sys, logging, logging.handlers, shutil
import arcpy

########################## user defined functions ##############################

def getDatabaseItemCount(workspace):
    log = logging.getLogger("script_log")
    """returns the item count in provided database"""
    arcpy.env.workspace = workspace
    feature_classes = []
    log.info("Compiling a list of items in {0} and getting count.".format(workspace))
    for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,datatype="Any",type="Any"):
        for filename in filenames:
            feature_classes.append(os.path.join(dirpath, filename))
    log.info("There are a total of {0} items in the database".format(len(feature_classes)))
    return feature_classes, len(feature_classes)

def replicateDatabase(dbConnection, targetGDB):
    log = logging.getLogger("script_log")
    startTime = time.time()

    if arcpy.Exists(dbConnection):
        featSDE,cntSDE = getDatabaseItemCount(dbConnection)
        log.info("Geodatabase being copied: %s -- Feature Count: %s" %(dbConnection, cntSDE))
        if arcpy.Exists(targetGDB):
            featGDB,cntGDB = getDatabaseItemCount(targetGDB)
            log.info("Old Target Geodatabase: %s -- Feature Count: %s" %(targetGDB, cntGDB))
            try:
                shutil.rmtree(targetGDB)
                log.info("Deleted Old %s" %(os.path.split(targetGDB)[-1]))
            except Exception as e:
                log.info(e)

        GDB_Path, GDB_Name = os.path.split(targetGDB)
        log.info("Now Creating New %s" %(GDB_Name))
        arcpy.CreateFileGDB_management(GDB_Path, GDB_Name)

        arcpy.env.workspace = dbConnection

        try:
            datasetList = [arcpy.Describe(a).name for a in arcpy.ListDatasets()]
        except Exception, e:
            datasetList = []
            log.info(e)
        try:
            featureClasses = [arcpy.Describe(a).name for a in arcpy.ListFeatureClasses()]
        except Exception, e:
            featureClasses = []
            log.info(e)
        try:
            tables = [arcpy.Describe(a).name for a in arcpy.ListTables()]
        except Exception, e:
            tables = []
            log.info(e)

        #Compiles a list of the previous three lists to iterate over
        allDbData = datasetList + featureClasses + tables

        for sourcePath in allDbData:
            targetName = sourcePath.split('.')[-1]
            targetPath = os.path.join(targetGDB, targetName)
            if not arcpy.Exists(targetPath):
                try:
                    log.info("Atempting to Copy %s to %s" %(targetName, targetPath))
                    arcpy.Copy_management(sourcePath, targetPath)
                    log.info("Finished copying %s to %s" %(targetName, targetPath))
                except Exception as e:
                    log.info("Unable to copy %s to %s" %(targetName, targetPath))
                    log.info(e)
            else:
                log.info("%s already exists....skipping....." %(targetName))

        featGDB,cntGDB = getDatabaseItemCount(targetGDB)
        log.info("Completed replication of %s -- Feature Count: %s" %(dbConnection, cntGDB))

    else:
        log.info("{0} does not exist or is not supported! \
        Please check the database path and try again.".format(dbConnection))

#####################################################################################

def formatTime(x):
    minutes, seconds_rem = divmod(x, 60)
    if minutes >= 60:
        hours, minutes_rem = divmod(minutes, 60)
        return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
    else:
        minutes, seconds_rem = divmod(x, 60)
        return "00:%02d:%02d" % (minutes, seconds_rem)

if __name__ == "__main__":
    startTime = time.time()
    now = datetime.datetime.now()

    ############################### user variables #################################
    '''change these variables to the location of the database being copied, the target 
    database location and where you want the log to be stored'''

    logPath = ""
    databaseConnection = "path_to_sde_or_gdb_database"
    targetGDB = "apth_to_replicated_gdb\\Replicated.gdb"

    ############################### logging items ###################################
    # Make a global logging object.
    logName = os.path.join(logPath,(now.strftime("%Y-%m-%d_%H-%M.log")))

    log = logging.getLogger("script_log")
    log.setLevel(logging.INFO)

    h1 = logging.FileHandler(logName)
    h2 = logging.StreamHandler()

    f = logging.Formatter("[%(levelname)s] [%(asctime)s] [%(lineno)d] - %(message)s",'%m/%d/%Y %I:%M:%S %p')

    h1.setFormatter(f)
    h2.setFormatter(f)

    h1.setLevel(logging.INFO)
    h2.setLevel(logging.INFO)

    log.addHandler(h1)
    log.addHandler(h2)

    log.info('Script: {0}'.format(os.path.basename(sys.argv[0])))

    try:
        ########################## function calls ######################################

        replicateDatabase(databaseConnection, targetGDB)

        ################################################################################
    except Exception, e:
        log.exception(e)

    totalTime = formatTime((time.time() - startTime))
    log.info('--------------------------------------------------')
    log.info("Script Completed After: {0}".format(totalTime))
    log.info('--------------------------------------------------')

5voto

cupakob Puntos 305

La única manera que usted puede obtener una copia fiel de los datos (dominios, conjuntos, relaciones, etc) es utilizar el manual de copiar y pegar método dentro del catálogo. ESRI no nos han dado la capacidad de transferir estos datos a través de cualquier otra forma con una única operación que puede ser programado fácilmente.

Tengo una noche de proceso que copia mis dos principales Bases de datos SDE para las geodatabases de archivos para la Continuidad de las Operaciones. Esto es para que en caso de una emergencia mi personal tiene algunos datos para trabajar con ellos hasta mi tienda puede reconstruir mi SDE de copia de seguridad. Después de mucho ensayo y error, he decidido que podemos vivir con las limitaciones de uso de FeatureClassToFeatureClass_conversion y TableToTable_conversion para la transferencia de nuestros datos a través de cada noche.

Sí, perdemos parte de la funcionalidad de la geodatabase, pero ahora va a ejecutar solos en la noche y está listo para ir tan pronto como lo reciba. En mi caso, la única funcionalidad que realmente nos falta (suponiendo que operan bajo un modo de emergencia) es que mis clases de relación se rompe debido a que la conversión se restablece el ObjectIDs que enlazan las dos tablas.

Hasta ESRI nos da más opciones que usted tendrá que mirar a qué estás dispuesto a sacrificar por el momento; el tiempo y el esfuerzo o la funcionalidad?

0voto

HoboSci Puntos 31

Si tienes privilegios de administrador puede utilizar los comandos copiar y pegar simple exportar o importar sde para el archivo de base de datos geográficos vise versa y mira aquí para más detalles.

Espero que este útil.!

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