Clone AGOL portal content to new AGOL portal

1374
8
02-26-2019 01:51 PM
ChaimSchwartz4
Occasional Contributor

Hi,

Using this notebook example provided online, I cloned an existing AGOL portal to a new AGOL portal.

The only two changes I really did were: (1) for testing purposes I'm running it only on one user at the time and (2) I had to create a new user name for the new AGOL org., since I can't have the same user name in two different AGOL subscriptions.

At first glance it seemed to have worked, all groups, folders and contents were moved to the new account and are under the ownership of the new user, however I cant actually access any of the hosted feature services, maps or webapps or surveys - receiving a message that the "layer cannot be added to the map", or that I "do not have access to this resource". This is actually also reflected when running the following line on my new user, which results in an empty list (allthough, as mentioned, I can actually see all items on my new account, and under my new ownership...). 

user1.items()

Based on these symptoms, can any body shed some light....?

Tags (1)
0 Kudos
8 Replies
AaronPulver
Esri Regular Contributor

Hi Chaim,

You should be able to use the clone_items method to deep clone an item and all of its dependencies. For example, if you cloned a webmap, it would clone the webmap and any layers it uses.

arcgis.gis module — arcgis 1.5.3 documentation 

example:

gis1 = GIS("https://arcgis.com", "username", "password")

gis2 = GIS("https://server.com/portal", "username", "password")

item = gis1.content.get("some-item-id")

cloned_items = gis2.content.clone_items([item])

BenKeller1
New Contributor

Aaron, I am running this method on a story map with multiple dependent web maps and dependent feature layers but none of the dependent items clone into my target portal. The story map itself comes through with the text, images, and videos. But no content. Any idea why this would be? 

0 Kudos
EarlMedina1
Occasional Contributor III

Chaim,

Aaron is absolutely correct - clone_items would be the better option for what you're hoping to achieve. To give you another example. here is one which I originally authored which you can modify to copy only certain item types: How To: Copy content from the Operations Dashboard of one Portal for ArcGIS or ArcGIS Online account... 

At the time of this writing, clone_items copies content between Administrator accounts so you will need to re-assign ownership. The good news, however, is that adding an argument to set the target owner is in the Product Plan.

ChaimSchwartz4
Occasional Contributor

When you say that clone_items works only with administrator accounts - do you mean only the initial administrator, or any administrator account?

I tried a very basic clone between two administrator accounts (one initial, one not) as shown below, but it won't work. Anything I'm missing? The item in the example is a simple line hosted feature service.

from arcgis.gis import GIS
from IPython.display import display

gis1 = GIS("https://esrica-services.maps.arcgis.com", "testMigration_pw", "XXXXXXX")
gis2 = GIS("https://esrica-pw.maps.arcgis.com", "testMigrationpw", "XXXXXXX")

item = gis1.content.get("05dc246acf9e41b0bef594ba81980da9")

cloned_items = gis2.content.clone_items([item])


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   1452                 # Explicitly add layers first and then tables, otherwise sometimes json.dumps() reverses them and this effects the output service
-> 1453                 feature_service = FeatureLayerCollection.fromitem(new_item)
   1454                 feature_service_admin = feature_service.manager

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\gis\__init__.py in fromitem(cls, item)
   8188     def fromitem(cls, item):
-> 8189         if not item.type.lower().endswith('service'):
   8190             raise TypeError("item must be a type of service, not " + item.type)

AttributeError: 'NoneType' object has no attribute 'type'

During handling of the above exception, another exception occurred:

_ItemCreateException                      Traceback (most recent call last)
<ipython-input-14-ab982857fca6> in <module>()
----> 1 cloned_items = gis2.content.clone_items([item])

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\gis\__init__.py in clone_items(self, items, folder, item_extent, use_org_basemap, copy_data, search_existing_items, item_mapping, group_mapping)
   3419             wgs84_extent = clone._wgs84_envelope(service_extent)
   3420         deep_cloner = clone._DeepCloner(self._gis, items, folder, wgs84_extent, service_extent, use_org_basemap, copy_data, search_existing_items, item_mapping, group_mapping)
-> 3421         return deep_cloner.clone()
   3422 
   3423     def bulk_update(self, itemids, properties):

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
    569     def clone(self):
    570         with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
--> 571             results = executor.submit(self._clone, executor).result()
    572             return results
    573 

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\_base.py in result(self, timeout)
    430                 raise CancelledError()
    431             elif self._state == FINISHED:
--> 432                 return self.__get_result()
    433             else:
    434                 raise TimeoutError()

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\_base.py in __get_result(self)
    382     def __get_result(self):
    383         if self._exception:
--> 384             raise self._exception
    385         else:
    386             return self._result

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\thread.py in run(self)
     54 
     55         try:
---> 56             result = self.fn(*self.args, **self.kwargs)
     57         except BaseException as exc:
     58             self.future.set_exception(exc)

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in _clone(self, excecutor)
    560                         if item:
    561                             item.delete()
--> 562                     raise ex
    563 
    564             level += 1

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\thread.py in run(self)
     54 
     55         try:
---> 56             result = self.fn(*self.args, **self.kwargs)
     57         except BaseException as exc:
     58             self.future.set_exception(exc)

C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   1755             return new_item
   1756         except Exception as ex:
-> 1757             raise _ItemCreateException("Failed to create {0} {1}: {2}".format(original_item['type'], original_item['title'], str(ex)), new_item)
   1758 
   1759 

_ItemCreateException: ("Failed to create Feature Service myLineLayer: 'NoneType' object has no attribute 'type'", None)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
EarlMedina1
Occasional Contributor III

Hi Chaim,

I meant you can't set a target owner yet. You can, however, find the items owned by Source User A (not necessarily the Source Admin account) and copy them to the content of Target Admin B. Then you re-assign to Target User B.

Try:

from arcgis.gis import GIS
from IPython.display import display

gis1 = GIS("https://esrica-services.maps.arcgis.com", "testMigration_pw", "XXXXXXX")
gis2 = GIS("https://esrica-pw.maps.arcgis.com", "testMigrationpw", "XXXXXXX")

item = gis1.content.get("05dc246acf9e41b0bef594ba81980da9")
data = [item]

gis2.content.clone_items(data,"test",copy_data=True)

 

It's been a while, but I recall having to create the list ahead of time. The "test" is the folder argument - basically, it'll create a folder named "test" and copy the content there.

-Earl

0 Kudos
EarlMedina1
Occasional Contributor III

Chaim,

Are you by any change copying between versions? I was able to reproduce that error between 10.4.1 and 10.6.1.

0 Kudos
EarlMedina1
Occasional Contributor III

Never mind - I see this was between AGOL.

0 Kudos
ChaimSchwartz4
Occasional Contributor

I don't have a clue why, but the same code is now working. I actually went back to this post and copy pasted the above code to make sure, but I can't reproduce the error, using the exact same portals, users and feature layer ID.  It even works with a non-administrative account in the target portal. Anyways, thank you very much Earl Medina‌ and Aaron Pulver‌ for the help with the cloning method.

0 Kudos