Select to view content in your preferred language

Problemas con saveACopy  y replaceDataSource

1198
5
07-03-2013 12:23 AM
angelurbano_rogel
Emerging Contributor
Hola,
tengo un para de problemas en un código que estoy realizando.
Resulta que quiero realizar el cambio de todas las capas de un mxd que está apuntando a una base de datos local por una conexión sde.
El código lo he simplificado pero quedaría algo así:


def change_layers(self, path_mxd):
        arcpy.env.overwriteOutput = True
       
        conex_sde  = self.gst_entorno.get_path_file_sde()
        mxd            = self.map_document(path_mxd)
       
        for df in arcpy.mapping.ListDataFrames(mxd):
            mxd.activeView = df.name
            self.__manage_layers(mxd, df, conex_sde)
           
            del df

       mxd.saveACopy(r'c:\temp\sde_mxd.mxd')

def __manage_layers(self, mxd, df, conex_sde):
        lyrs     = arcpy.mapping.ListLayers(mxd, '', df)                              
        for i in range (0, len(lyrs)):
          
            i_ly      = lyrs
            i_ly_name = i_ly.name          
            if i_ly.isFeatureLayer:
                self.__change_feature(i_ly, conex_sde)
           
            del i_ly
       
        del lyrs
       
        return True

def __change_feature(self, ly_feature, conex_sde):
        table_name = ly_feature.datasetName           
        ly_feature.replaceDataSource(conex_sde, "SDE_WORKSPACE", table_name, False)       
       
        return True


tengo dos problemas.
1) al realizar el saveACopy, cuando el número de capas a cambiar es alto me da un error:

MapDocObject: Unable to save.  Check to make sure you have write access to the specified file and that there is enough space on the storage device to hold your document.

Tengo la sensación que no acaba de realizar el copy del mxd cuando intenta ponerse en escritura sobre el mismo, dando el error que indico, que es el mismo que si tuviera el mxd abierto y lo intentase modificar.

2) Al realizar el replaceDataSource tarda bastante, y si el número de capas es alto, algo que puede ser habitual, el coste en tiempo es muy algo. Se os ocurre alguna forma para poder optimizarlo?

Gracias por adelantado.
Tags (2)
0 Kudos
5 Replies
LucasDanzinger
Esri Frequent Contributor
It's kind of hard to tell what the issue is with the way the code is formatted above, but are you trying to save a copy inside of a loop? If you are, then perhaps it is trying to save a new copy with the same name every time you replace a layer's data source, which I could see causing locking issues. I suggest you first move the save a copy outside of the loop if it is in a loop, and if it is not, re-post your code with the code tags so it is easier to read. If you are trying to save a copy several times, this could add to the slower performance as well.
0 Kudos
angelurbano_rogel
Emerging Contributor
Hola de nuevo

os paso el código con los tabuladores.
--------------------------------------
import arcpy

def change_layers(self, path_mxd):
arcpy.env.overwriteOutput = True

conex_sde = self.gst_entorno.get_path_file_sde()
mxd = self.map_document(path_mxd)

for df in arcpy.mapping.ListDataFrames(mxd):
  mxd.activeView = df.name
  self.__manage_layers(mxd, df, conex_sde)

  del df

mxd.saveACopy(r'c:\temp\sde_mxd.mxd')
del mxd

def __manage_layers(self, mxd, df, conex_sde):
lyrs = arcpy.mapping.ListLayers(mxd, '', df)
for i in range (0, len(lyrs)):

  i_ly = lyrs
  i_ly_name = i_ly.name
  if i_ly.isFeatureLayer:
   self.__change_feature(i_ly, conex_sde)

  del i_ly

del lyrs

return True

def __change_feature(self, ly_feature, conex_sde):
table_name = ly_feature.datasetName
ly_feature.replaceDataSource(conex_sde, "SDE_WORKSPACE", table_name, False)

return True

-----------------------

empiezo a pensar que puede ser algo muy concreto de mi instalación, máquina, versión de fichero, porque no encuentro otra explicación para este problema.

Si que os diré que el origen de estos ficheros son de la 9.3. y estoy trabajando con una 10.1. Pero ya os adelanto que previamente los he guardado como 10.1. para evitar posibles problemas...
0 Kudos
angelurbano_rogel
Emerging Contributor
Atacho fichero con el código, ya que no soy capaz de que salgan las tabulaciones en el foro.

Empiezo a pensar que el problema está en mi máquina, algún problema con la instalación o con mi versión de python, ya que no he visto que haya ningún caso parecido.

se os ocurre algo que pueda mirar y que pueda afectar?.
0 Kudos
SchoppMatthieu
Deactivated User
Hola,
Que te parece usar : replaceWorkspaces

Works great for me
:

[HTML]mxdArray = [mxdInfra, mxdCroquis, mxdOverView, mxdTerritoires, mxdPaysageA4, mxdPaysageA3, mxdPaysageA2, mxdPaysageA1, mxdPaysageA0, mxdLegend, mxdSimpleCarte]

for mxd in mxdArray:
   
    for df in arcpy.mapping.ListDataFrames(mxd):

        print ('-----------------------------------')
        print ("LISTE DES SOURCES DE DONNEES A REMPLACER :")
        print ('-----------------------------------')
   
        for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
            if lyr.supports("DATASOURCE"):
                print lyr.dataSource

        print ('-----------------------------------')
        print ("REMPLACEMENT DES SOURCES DE DONNEES :")
        print ('-----------------------------------')
   
        mxd.replaceWorkspaces(originalDataSourceGAIA, "FILEGDB_WORKSPACE", newDataSourceGAIA, "SDE_WORKSPACE", False)
        mxd.replaceWorkspaces(originalDataSourceSIGEXT, "FILEGDB_WORKSPACE", newDataSourceSIGEXT, "SDE_WORKSPACE", False)
        mxd.replaceWorkspaces(originalDataSourceSIGGAIA, "FILEGDB_WORKSPACE", newDataSourceSIGGAIA, "SDE_WORKSPACE", False)
   
        print ('-----------------------------------')
        print ("REMPLACEMENT DES SOURCES DE DONNEES EFFECTUE")
        print ('-----------------------------------')


        print ('-----------------------------------')
        print ("LISTE DES NOUVELLES SOURCES DE DONNEES :")
        print ('-----------------------------------')
        for lyrChanged in arcpy.mapping.ListLayers(mxd, data_frame=df):
            if lyrChanged.supports("DATASOURCE"):
                print lyrChanged.dataSource

        print ('-----------------------------------')
        print ("SAUVEGARDE DU MXD :")
        print ('-----------------------------------')
        mxd.save()
       
    del mxd, df[/HTML]
0 Kudos
angelurbano_rogel
Emerging Contributor
Perfecto, mucho más óptimo y evito el problema con el saveACopy. haciéndolo de esta forma no me da el error.
Por dejar constancia, creo que el problema podría derivar de la conexión SDE, ya que realizando los mismo cambios teniendo como destino una base de datos GDB no me daba ningun problema.

Lo único que me queda es saber obtener de manera dinámica el type_workspace de origen, he visto el método arcpy.Describe(old_workspace), pero no me da la información que requiero. Por lo que he visto no me queda otra opción que tratar las extensiones de fichero:

[HTML]
TYPE_ACCESS_WORKSPACE    = 'ACCESS_WORKSPACE' # �?? A personal geodatabase or Access workspace
TYPE_FILEGDB_WORKSPACE   = 'FILEGDB_WORKSPACE' # �??A file geodatabase workspace
TYPE_SDE_WORKSPACE       = 'SDE_WORKSPACE' #�??An SDE geodatabase workspace
TYPE_SHAPEFILE_WORKSPACE = 'SHAPEFILE_WORKSPACE' #�??A shapefile workspace

def type_workspace(self, path_workspace):
        ext = path_workspace.split(".")[-1].upper()
        type_workspace = None
        if (ext == 'MDB'):
            type_workspace = self.TYPE_ACCESS_WORKSPACE
        elif (ext == 'GDB'):
            type_workspace = self.TYPE_FILEGDB_WORKSPACE
        elif (ext == 'SDE'):
            type_workspace = self.TYPE_SDE_WORKSPACE
        elif (ext == 'SHP'):
            type_workspace = self.TYPE_SHAPEFILE_WORKSPACE

       return type_workspace

[/HTML]
0 Kudos