Clone surveys from one organization to another

7126
19
05-12-2021 09:55 AM
ZacharySutherby
Esri Regular Contributor
8 19 7,126

Introduction:

A common question the Survey123 team has received from organization administrators is, "What's the best way to clone my surveys from one organization to another?"

There are two common use cases for cloning surveys:

  1. Create a copy of a survey in another ArcGIS organization. For example, a city’s transportation and water departments have different ArcGIS Online organizations and the water department would benefit from having a copy of one of the transportation department’s surveys as well as its associated web map and dashboard.
  2. Clone a survey from a development organization in ArcGIS Enterprise to staging and production organizations.

This blog and sample Python notebook demonstrate how to clone surveys and associated content from one organization to another. This workflow can be used to clone surveys from ArcGIS Online to ArcGIS Online, ArcGIS Online to ArcGIS Enterprise, or ArcGIS Enterprise to ArcGIS Enterprise. The direction of cloning does not matter.

The foundation of the workflow is the clone_items() method in the ArcGIS API for Python. This is the infrastructure that allows us to clone surveys from a source organization to a target organization. Given the different content and item types, possible ArcGIS Enterprise configurations, potential ArcGIS Online configurations, security considerations, and item dependencies, the clone_items() method aims to produce an exact duplicate of an item that retains all of its functionality.

Please note that cloning relies on the sharing model to determine the items a user can clone. If a user can access an item, that user can clone it. However, a user can’t create any items in the target organization if they don’t have the appropriate privileges to create.

For more in-depth content on how the clone_items() method works please review the ArcGIS API for Python Guide on cloning content, as well as the documentation.

A copy of the full notebook is available for download in our Survey123-tool GitHub repo

Prepare to clone:

To start, we are going to need two GIS connections; one to our “source” organization, which is the organization in which the survey and content currently resides that we would like to clone; and another to a “target” organization, which is the organization that we would like to clone the survey and content to.

ZacharySutherby_0-1620837642858.png

In our first example we are going to highlight a workflow where we have a few surveys shared to a group that we would like to clone to a different organization. In order to work with our surveys a Survey Manager is defined. A survey in the Survey Manager is a single instance of a survey project that contains the item information, properties, and provides access to the underlying survey dataset. Please use this link for more information on working with the Survey Manager. In this example, four surveys are shared to a group. Using the group ID, a connection is made to the group and a list is created containing all form items within the group.

ZacharySutherby_1-1620837792091.png

Now that we have our forms as a list, we are ready to clone the content from our source organization to the target organization. As previously noted, a use case for using the clone_items() method is to clone surveys between development, staging, and production organizations. This first example clones the surveys from our existing group (as defined above) located in the source organization to the target organization and shares the cloned surveys to a group with the same name in the target organization.

Clone related items:

The code below starts by creating a new group in the target organization using the same title and tags as the existing group in the source organization. Once the surveys are cloned, they will be shared to this newly created group.

Each form item in the source group is looped through, obtaining the feature service associated with the survey through the “Survey2Service” relationship, as well as any additional items related to the survey using the “Survey2Data” relationship. This would include any linked content or report templates associated with the survey. All related items are merged into a list to be cloned. Please review the relationship types documentation for more information on related items in ArcGIS.

Next, a new folder in the target organization is created based on the survey name, and the items in the list are cloned. Since the `copy_data` parameter is set to “False” in the clone_items() method, the resulting services created in the target organization will not contain any data. This is ideal when cloning from a development environment to a staging or production environment, as you might not wish to retain any test data.

Finally, the form items are shared to the group in the target organization that was defined previously, including the feature service, and tags are added to each item.

ZacharySutherby_5-1620838103417.png

As a confidence check, let’s query the newly created group and confirm our four surveys have been shared.

ZacharySutherby_6-1620838174324.png

The example above is a useful workflow for cloning surveys between development, staging, and production environments, and will only clone items that are linked to the form item including: report templates, linked web maps, CSVs, and map packages. But what if we would like to clone not only the survey and its related items, but also the survey data that’s already been collected? Additionally, what if we have web maps that aren’t linked to the survey, web apps, or dashboards that use the survey data?

If those items are stored in the survey’s folder, a slightly different method can be used to clone all the content from this folder.

Clone full survey folder:

The code below demonstrates connecting to one specific survey within our organization. Using the properties of the survey, the folder ID where the survey resides is assigned to a variable. Next, all the folders in the source organization for the source username are listed. Using list comprehension, the folder in the `full_folder` variable is matched with the folder ID obtained from the survey properties.

Once the correct folder has been identified the contents of the folder are listed.

ZacharySutherby_7-1620838220627.png

Now that all items to be cloned are in a list, a new folder is created in the target organization to store the content. After the folder is created the content is cloned to the target environment. Since the `copy_data` parameter is not defined the default value for the parameter is “True”, meaning all the underlying data will also be cloned. This means the resulting content in the target organization will be an identical clone of the original data. If you do not wish to retain the source data, setting the `copy_data` parameter to “False” will only clone the data schema and architecture to the target organization. Meaning the survey, web maps, web apps, dashboards etc. will configured as per their original items; the only difference is the feature layer will be empty.

ZacharySutherby_8-1620838309224.png

In this blog we’ve covered two use cases of using the clone_items() method. This sample notebook is intended to be used as a guide; you can take what’s here and incorporate it into your own workflows.

What workflows or use cases do you have that we missed? Please let us know your use cases and workflows and we can work on incorporating them into the notebook.

Notes on limitations:

  • Clone Fails with Non-Ascii Characters in Service Name
  • Cloning is limited to 1000 records
19 Comments
MillerDerek
Emerging Contributor

Is cloning from an on-premises Portal to Arcgis.com supported?

I can successfully clone the survey folder and all items from portal - arcgis.com, but survey123 does not recognize the survey. Survey123 errors with 'The survey does not exist or is not accessible.' 

I submitted a bug report on this issue as well. Thanks.

ZacharySutherby
Esri Regular Contributor

Hello @MillerDerek

Cloning from an internal Enterprise organization to ArcGIS Online is a supported workflow. Are you using a registered feature service with your survey (is the service pointing to an enterprise geodatabase)?

On the item details page of the Form item created in ArcGIS Online there will be a Layers section halfway down the page. In that Layers section does it have the link to the hosted feature layer in your ArcGIS Online organization?

Thank you, 

Zach

MillerDerek
Emerging Contributor

Hi @ZacharySutherby 

 

No, the survey created in the internal enterprise org is using a hosted feature service. And, no, the form item in ArcGIS Online (post clone) lacks a layer section on the item.

 

Thank you,

Derek

ZacharySutherby
Esri Regular Contributor

Hello @MillerDerek

Thank you for confirming. Prior to cloning, both workflows in the notebook print the items that are going to be cloned. Are you seeing the hosted feature service in that list of items that will be cloned? Are you seeing any error messages in the script after the clone function finishes? 

If you are, are you seeing the hosted feature service created in your ArcGIS Online content, just the link between the form item and the hosted feature service seems to be broken, or is the hosted feature service not present in ArcGIS Online at all? 

If the hosted feature service isn't present in ArcGIS Online at all here is a mini python script that you can use to clone just the hosted feature service and see if that works. 

Thank you, 

Zach

MillerDerek
Emerging Contributor

Hi @ZacharySutherby 

I appreciate your replies and assistance.

Prior to cloning, both workflows in the notebook print the items that are going to be cloned...

-- Yes, I'm seeing the hosted service in the list of items to be cloned. No, there are no error messaged.

... or is the hosted feature service not present in ArcGIS Online at all? 

-- Each item within the survey folder (form item, hosted feature services (multiple)) is cloned from Portal to is present Arcgis.com

I have a case open with support. I had a screen share session with @AniketKokate this morning and was able to reproduce the behavior from survey creation -- clone -- error.

I'm going to insert 4 photos:

  1. Contents of the survey folder in Portal
  2. Contents of the survey folder in Arcgis.com
  3. Cloned survey in Survey123 website
  4. Error when attempting to open cloned survey in Survey123 website

 portal-folder-contents.pngarcgis-folder-contents.pngcloned-survey.pngsurvey123-result.png

 

KrishV
by
Frequent Contributor

Hi @ZacharySutherby ,@MillerDerek ,

This blog post is really helpful. I have tried this workflow from ArcGIS Online to ArcGIS Online and it works Perfectly.

 

I have tried the Clone full Survey Folder from ArcGIS Online to ArcGIS Enterprise and also from ArcGIS Enterprise to ArcGIS Enterprise. In both cases, I get "The Survey does not exist or is not accessible". 

Is there any work around to fix this? Please suggest.

 

Thanks,

Krish

 

MillerDerek
Emerging Contributor

Hi @KrishV, @ZacharySutherby - Same behavior I have experienced. I have not yet found a solution or work around. Nor has Esri support at this time. I'll reply to this thread if a solution is found.

Thanks

- derek

ZacharySutherby
Esri Regular Contributor

The issue with cloning between ArcGIS Online and Enterprise and vice versa using surveys created in the web has been resolved in the notebook present in the GitHub repo. Please use the latest version of the notebook in the Survey123-tools repo to work around the issue. 

gvanderwaal
Emerging Contributor

Hi @ZacharySutherby,

I've thrown together a script based on this cloning guide, except using clone_items() instead of copy_items(). Things clone as expected, but images associated with individual survey questions in the source (AGO) lose that association in the target (Enterprise). They're still present in the target feature service, just as "attachments" and do not display when generating reports. Below are screenshots of how they appear through the Survey123 website.

gvanderwaal_1-1627679871853.png

gvanderwaal_2-1627679963253.png

This makes me think there's a relationship not being cloned or restored by Survey2Data or Survey2Service, but these are the only two from the list that show up as active during my testing. What am I missing?

Submissions to the survey post-cloning work as expected - images are associated with survey questions, showing up as expected in reports and in the data.

ZacharySutherby
Esri Regular Contributor

Hey @gvanderwaal

Thank you for reaching out! Survey123 uses keywords to associate what attachment goes with what image question. One thing to confirm is your ArcGIS Enterprise organization will need to be at version 10.8.1 or later as pre-10.8.1 organizations don't support attachment keywords. 

If your Enterprise organization is 10.8.1 or later when the data was cloned into the ArcGIS Data Store it may not have brought over the keywords. You can check if the attachment schema has keywords by navigating to the REST endpoint of the feature service in your Ent org, navigate to the layer, append any object ID that you know has attachments, and append /attachments to the URL. It will look something like https://<FQDN>/<webAdaptor>/ArcGIS/rest/services/<serviceName>/FeatureServer/0/<anyOID>/attachments. The page should look like this: 

ZacharySutherby_1-1627682181693.png

 

If that Keywords attribute is in your attachment tables schema (like in the photo above) and the value is empty we have a notebook that you can use to automate the process of updating each attachment with their respective keyword. Luckily from the image you shared it looks like the keyword is in the name of the image (in your case image1) and the notebook can extract that and use the name of the image to determine the keyword. 

If that Keywords attribute is not in your attachment tables schema (it's missing on the attachment infos page) please download your feature service as a file geodatabase and open the data in ArcGIS Pro. There is a Geoprocessing tool called Upgrade Attachments in Pro that you can use to enable attachment keywords for your attachment table. When the tool finishes please overwrite your feature service and then run the notebook from above to update the attachment keywords. 

Please let me know if you would like to schedule a call to discuss this and I would be happy to help out! 

Thank you, 

Zach

 

gvanderwaal
Emerging Contributor

@ZacharySutherbyThank you, missing keywords was the issue, I was able to successfully update a keyword manually, and I got the script to work. I appreciate the quick reply!

StuartMoore
Frequent Contributor

would this work if i wanted to clone (copy) a single survey return within the same survey, so that i could update something on the copy but maintain the original for audit reasons

Stu

ZacharySutherby
Esri Regular Contributor

Hello @StuartMoore

Yes this workflow can be used to clone a single survey within the same organization, you would just need the code from the Clone full survey folder section of the sample notebook. Although if your survey was created in the Survey123 website you can use the "Save as" option in the website to create a copy of your survey. 

Thank you, 

Zach

StuartMoore
Frequent Contributor

thanks Zach i'll have a play 😊

Stu

StuartMoore
Frequent Contributor

thanks @ZacharySutherby i had a play but it clones the actual survey (ie the forms you open in survey123) rather than a specific survey return

thanks anyway

 

Stu

MillerDerek
Emerging Contributor

Hi Stuart – that’s the intended behavior as far as I understand it.

If I needed to ‘clone’ a single record from one survey to an identical-but-separate survey, I would go directly to the hosted feature layer behind the survey. Query the source and apply edits to the target, so to speak. The implementation would be subject to your survey configuration (data access, etc.), I would assume.

That sound reasonable, @ZacharySutherby ?

ZacharySutherby
Esri Regular Contributor

Hello @StuartMoore

@MillerDerek is correct the clone_items() method will clone the full item instead of a specific record in a survey. Please see the clone_items() Python API documentation for more information. 

Thank you, 

Zach

StuartMoore
Frequent Contributor

thanks @ZacharySutherby & @MillerDerek 

 

Stu

LuisAntonioRodriguezGonzalez
Emerging Contributor

I have an issue cloning from AGOL to Enterprise (10.8.1).

ParseError                                Traceback (most recent call last)
~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in update_form(self, target, new_item, clone_mapping)
   5151                                     )
-> 5152                                     payload["form"] = self._replace_form(   5153                                         form, field_mapping

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in _replace_form(self, xml_string, lookup)
   4938     def _replace_form(self, xml_string: str, lookup: dict) -> str:
-> 4939         xml = ElementTree.fromstring(xml_string)
   4940 

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\xml\etree\ElementTree.py in XML(text, parser)
   1341         parser = XMLParser(target=TreeBuilder())
-> 1342     parser.feed(text)
   1343     return parser.close()

ParseError: mismatched tag: line 5, column 615

During handling of the above exception, another exception occurred:

Exception                                 Traceback (most recent call last)
~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   5013                 original_item = self.info
-> 5014                 self.update_form(self.target, new_item, self._clone_mapping)
   5015             _share_item_with_groups(

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in update_form(self, target, new_item, clone_mapping)
   5265         except Exception as ex:
-> 5266             raise Exception(   5267                 "Failed to update {0} {1}: {2}".format(

Exception: Failed to update Form PRUEBA_DE_FECHA: mismatched tag: line 5, column 615

During handling of the above exception, another exception occurred:

_ItemCreateException                      Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_21608\3352823519.py in <cell line: 1>()
----> 1 clonarItemsSurvey(portal, nombreCarpetaClon, False, [itemsAClonar[1]])

~\AppData\Local\Temp\ipykernel_21608\2075108364.py in clonarItemsSurvey(portal, nombreCarpetaClon, borrarDatosFeatureService, itemsAClonar)
     11     print("Clonando items ...")
     12     print("\t¿Borrar datos del feature service asociado?: {}".format(borrarDatosFeatureService))
---> 13     clonedItems = portal.content.clone_items(items=itemsAClonar, folder=nombreCarpetaClon)
     14     '''
     15     if borrarDatosFeatureService:

~\AppData\Local\Programs\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, copy_global_ids, search_existing_items, item_mapping, group_mapping, owner, preserve_item_id)
   7902             preserve_item_id=preserve_item_id,
   7903         )
-> 7904         return deep_cloner.clone()
   7905 
   7906     def bulk_update(

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   1216 
   1217             with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
-> 1218                 results = executor.submit(self._clone, executor).result()
   1219                 return results
   1220 

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\_base.py in result(self, timeout)
    444                     raise CancelledError()
    445                 elif self._state == FINISHED:
--> 446                     return self.__get_result()
    447                 else:
    448                     raise TimeoutError()

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\_base.py in __get_result(self)
    389         if self._exception:
    390             try:
--> 391                 raise self._exception
    392             finally:
    393                 # Break a reference cycle with the exception in self._exception

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\thread.py in run(self)
     56 
     57         try:
---> 58             result = self.fn(*self.args, **self.kwargs)
     59         except BaseException as exc:
     60             self.future.set_exception(exc)

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in _clone(self, excecutor)
   1189                         if item:
   1190                             item.delete()
-> 1191                     raise ex
   1192 
   1193             level += 1

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\concurrent\futures\thread.py in run(self)
     56 
     57         try:
---> 58             result = self.fn(*self.args, **self.kwargs)
     59         except BaseException as exc:
     60             self.future.set_exception(exc)

~\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   5021 
   5022         except Exception as ex:
-> 5023             raise _ItemCreateException(   5024                 "Failed to create {0} {1}: {2}".format(
   5025                     original_item["type"], original_item["title"], str(ex)

_ItemCreateException: ('Failed to create Form PRUEBA_DE_FECHA: Failed to update Form PRUEBA_DE_FECHA: mismatched tag: line 5, column 615', <Item title:"PRUEBA_DE_FECHA" type:Form owner:admin>)