ArcSDE coğrafi veritabanını ArcPy kullanarak coğrafi veritabanına mı kopyalıyorsunuz?


9

Bir dosya geodatabase SDE veritabanının tam bir kopyasını (etki alanları, özellik veri kümeleri, özellik sınıfları, vb.) Yapmak istiyorum.

Ben de dahil olmak üzere çeşitli olasılıkları denedim:

  1. Kopyalama (Veri Yönetimi) işlemini kullanma
  2. yeni bir GDB oluşturma ve her özellik veri kümesini SDE'den manuel olarak kopyalama
  3. xml çalışma alanı belgesini SDE'den dışa aktarma ve GDB'ye aktarma

Copy_managementGiriş ve çıkış veri tipleri aynı olmalıdır çünkü, bir GDB bir SDE kopyalamak için çalışacak gibi işlem görünmüyor.

Her özellik veri kümesini yeni bir GDB'ye içe aktarma işlemi, muhtemelen her özellik veri kümesini yineleyerek Copy_management kullanılarak otomatikleştirilebilir, ancak işlemlerden birinde bir hata varsa bu eksik bir kopyanın sorunlarına neden olabilir.

Xml çalışma alanlarını dışa ve içe aktarmak işe yarıyor gibi görünse de, bu işlem büyük coğrafi veri tabanlarında kullanıldığında inanılmaz derecede büyük dosyalar oluşturur.

Bir SDE'nin içeriğini ve şemasını bir GDB'ye, otomatikleştirilebilecek bir şekilde, belirtilen yollardan bir GDB'ye kopyalamanın daha basit bir yolu var mı?

Değilse, yukarıdaki olasılıkların bu süreçte kullanılmaması için herhangi bir neden var mı?


Yanıtlar:


5

Verilerin gerçek bir kopyasını (etki alanları, veri kümeleri, ilişkiler vb.) Almanın tek yolu, katalog içindeki el ile kopyala ve yapıştır yöntemini kullanmaktır. ESRI henüz bize bu verileri kolayca yazılabilen tek bir işlemle başka bir yolla aktarma yeteneği vermedi.

İki temel SDE Veritabanımı Operasyonların Sürekliliği için coğrafi veri tabanlarına kopyalayan her gece işlemim var. Bu, acil bir durumda, BT mağazamın SDE'mi yedeklemeden yeniden oluşturabilene kadar personelimin birlikte çalışması için bazı verileri olması. Birçok deneme yanılma işleminden sonra , verilerimizi her gece aktarmak için FeatureClassToFeatureClass_conversion ve TableToTable_conversion kullanma sınırlamalarıyla yaşayabileceğimize karar verdim .

Evet, coğrafi veritabanının bazı işlevlerini kaybediyoruz, ancak şimdi geceleri katılımsız çalışacak ve alır almaz kullanıma hazır. Benim durumumda gerçekten eksik olduğumuz tek işlevsellik (acil durum modu altında çalıştığı varsayılarak), dönüşüm iki tabloyu bağlayan ObjectID'leri sıfırladığı için ilişki sınıflarımın bozuk olmasıdır.

ESRI bize daha fazla seçenek sunana kadar, şu anda neyi feda etmek istediğinize bakmak zorunda kalacaksınız; zaman ve çaba veya işlevsellik?


Bir xml worskspace doc işe ​​yaramaz mı?
Jyler

8

Bu yazının biraz eski olduğunu biliyorum ama aynı sorunla karşılaştığım için cevabımı paylaşacağım. Aşağıdaki komut dosyası, bir veri kümesinde olmayan tüm tabloları, özellik sınıflarını ve ilişkileri kopyalamalıdır ve ayrıca veri kümesindeki özellik sınıfları, topoloji vb. Dahil tüm veri kümelerini kopyalayacaktır. Kopyala adn devam ederken herhangi bir hata atlayacak. Kaynak DB öğe sayısı ve hedef öğe sayısı gibi verileri içeren bir günlük dosyası oluşturur, böylece kopyayı karşılaştırabilirsiniz ve karşılaştığı hataları da günlüğe kaydeder.

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)   

Bununla gerçekten iyi şanslar yaşadım. SDE veritabanını bir dosya coğrafi veritabanına çoğaltma. Tüm senaryolarımı karşıladığından beri bu senaryo üzerinde çok fazla test yapmadım. ArcGIS 10.3 kullanarak test ettim. Ayrıca, dikkat edilmesi gereken bir şey, bu komut dosyasını kullanan biriyle görüşmeler yapıyordum ve uygun olmayan izinler ve boş tablolar nedeniyle belirli veri kümelerini kopyalarken bir hatayla karşılaştılar.

Lemur - ilişkilerinizi neden nesne kimliği yerine global bir tanıtıcıya dayalı oluşturmuyorsunuz? Sizin ilişkilerinizin korunacağını. Global kimlik oluşturmadıysanız, kesinlikle tavsiye ederim.

-Güncelleme

Ben kötü veritabanı bağlantı yolları ve daha iyi günlük ve hata işleme işlemek için koda biraz daha mantık ekledim:

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('--------------------------------------------------')

Peter, sağladığınız senaryoyu kullandım ve alttaki 2 değişkeni güncelledim. Bir hata izleme alıyorum (en son çağrı son): Dosya "ServerPath \\ CopySDEtoGDB.py", satır 90, <module> replicateDatabase (databaseConnection, targetGDB) Dosya "ServerPath \\ CopySDEtoGDB.py", satır 55, reppyateDatabase datasetList = [arcpy.Describe (a) .name in a arcpy.ListDatasets ()] TypeError: 'NoneType' nesnesi yinelenemez Bu ne anlama geliyor?
Courtney

Courtney - Veritabanı bağlantı değişkeninizin yolunda bir yazım hatası veya küçük bir hata varmış gibi görünüyor. Bu satır 55 boş bir liste üzerinde yinelemeye çalışıyor çünkü bir hata atıyor. "DatabaseConnection" değişkeni yanlış yolunu kullanarak aldığınız hatayı yeniden oluşturmak başardı. Değişkende kullandığınız gerçek yol nedir?
PMK

Bunu her gece yapmak istersem, mevcut özelliklerin üzerine yazmaz mı? Sadece mevcut hedefin üzerine yazmak istediğim her seferinde yeni bir FGD oluşturmak istemiyorum.
NULL.Dude

Hedef GDB varsa Peter komut dosyası başarısız olur
NULL.Dude

2

Peter daha yukarıda benzer bir komut dosyası kullandım ve onun daha iyi olmasına rağmen, iyi şanslar vardı. Birisi trip olabilir işaret etmek bir şey 64 bit python geoprocessing kullanıyorsanız ve ESRI üstünde ArcFM yüklüyse, bir ERROR 000260 ile ArcFM veya Designer kullanmak için ayarlanmış tüm özellikleri başarısız olacaktır. 32 bit python kullanmanız veya ArcFM öğelerinin düzgün şekilde lisanslanmamasıdır.

32 bit ArcPy kullanmanın daha ayrıntılı bir açıklaması için Exchange'deki bu iş parçacığındaki ilk iki yoruma bakın

https://infrastructurecommunity.schneider-electric.com/docs/DOC-2563


Bu iki yorum bu sorunun cevabını sağlıyorsa, içeriği burada alıntılanmalı veya özetlenmeli ve sadece bağlantılı olmamalıdır - bkz. Meta.stackexchange.com/questions/225370/… Bir özet sağladıysanız , belki de sadece değiştirin. "Daha ayrıntılı bir açıklama için Exchange'de bu iş parçacığındaki ilk iki yoruma bakın" - "Exchange'de bu iş parçacığının ilk iki yorumu".
PolyGeo

0

Yönetici ayrıcalıklarınız varsa, sde'yi coğrafi veritabanına tersine veya dışa aktarmak için basit kopyalama ve yapıştırma komutlarını kullanabilirsiniz ve daha fazla ayrıntı için buraya bakın.


Teşekkürler Ganeshnarim - Python kullanarak işlemi otomatikleştirmek istiyorum, bu yüzden ArcCatalog'daki herhangi bir manuel kopyala / yapıştır işlemi ihtiyaçlarıma uymuyor. Ben de (ArcMap 10.1'de) bir SDE kopyalamak aynı veritabanına başka bir bağlantı oluşturur (bu aynı teknik bir dosya veya kişisel coğrafi veritabanında kullanılmış olsaydı, bir kopya yapılır) göründüğü gibi, bu yöntemle sınırlı başarı elde ettim
Krausers
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.