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....?
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])
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?
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.
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)
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
Chaim,
Are you by any change copying between versions? I was able to reproduce that error between 10.4.1 and 10.6.1.
Never mind - I see this was between AGOL.
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.