Sé que esta publicación es un poco vieja, pero pensé que compartiría mi respuesta ya que me enfrenté al mismo problema. El siguiente script DEBE copiar todas las tablas, clases de entidad y relaciones que no estén en un conjunto de datos y también copiará sobre todos los conjuntos de datos, incluidas las clases de entidad, la topología, etc. dentro del conjunto de datos. Se saltará cualquier error durante la copia y continuará. Producirá un archivo de registro que contiene datos como el recuento de elementos de la base de datos de origen y el recuento de elementos de destino para que pueda comparar la copia y también registrará los errores que encuentre.
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)
Tuve mucha suerte con esto. Estaba replicando una base de datos SDE en una geodatabase de archivos. Sin embargo, no he realizado pruebas exhaustivas con este script, ya que satisfizo todas mis necesidades. Lo probé usando ArcGIS 10.3. Además, una cosa a tener en cuenta, estaba en conversaciones con alguien que ha usado este script y se encontraron con un problema con un error al copiar ciertos conjuntos de datos debido a permisos incorrectos y tablas vacías.
Lemur: ¿por qué no crear sus relaciones basadas en una identificación global en lugar de la identificación del objeto? Que tus relaciones se preservarían. Si no ha creado identificaciones globales, lo recomendaría encarecidamente.
-actualizar
Agregué un poco más de lógica al código para manejar rutas de conexión de base de datos incorrectas y un mejor registro y manejo 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('--------------------------------------------------')