ArcGIS Online フィーチャ レイヤーから添付ファイル(例:写真やドキュメント)をダウンロードする方法に関する質問をよく受けます。これの目的は、現在提供されている方法に代わるソリューションを提供することです。<\/P>
<\/P>
まず、ArcGIS Online でデータをエクスポートする際に添付ファイルが含まれる唯一の方法は、ファイル ジオデータベースとしてエクスポートする場合です。その理由は、ファイル ジオデータベースが関連レコードをサポートする唯一の形式だからです。したがって、ArcGIS Online 以外でフィーチャ レイヤーの添付ファイルにアクセスする最も一般的な回答は、フィーチャ レイヤーをファイル ジオデータベースとしてエクスポートし、スクリプトを使ってデータを抽出することです。こちらのようなスクリプト<\/A>を ArcGIS Desktop を通じて使用します。また、同期スクリプト<\/A>もあり、ローカルのファイル ジオデータベースとホストされたフィーチャ レイヤーを同期できます。これらはうまく機能しますが、ArcGIS Desktop に依存しており、オプション1の場合はスクリプト実行前にファイル ジオデータベース(データ追加によりサイズが大きくなる可能性があります)をダウンロードする必要があります。<\/P><\/P>このため、新しい ArcGIS API for Python<\/A> を使ったスクリプトを作成しました。これは ArcGIS Desktop とは独立して動作します。実際には Web GIS と直接連携するため、添付ファイルにアクセスするためにファイル ジオデータベースをダウンロードする必要すらありません。このスクリプトは定期的に再実行でき、以前にダウンロードされていない新しい添付ファイルのみをディスクにダウンロードします。<\/P><\/P>このスクリプトは何をするのか?<\/STRONG><\/P><\/P>フィーチャ 添付ファイルを保存するフォルダー(例:Attachment Downloads)を作成します<\/LI>このフォルダー内に指定されたフィーチャ レイヤーの各レイヤーごとにサブフォルダーを作成しますAttachmentStorage 変数が 'GroupedFolder<\/SPAN>' に設定されている場合、添付ファイルは ObjectId-AttachmentId-OriginalFileName の形式で単一フォルダー内に保存されます<\/LI>AttachmentStorage 変数が 'IndividualFolder' に設定されている場合、添付ファイルがある各フィーチャごとに新しいフォルダー(フィーチャの Object ID を名前として)を作成し、その中に AttachmentId-OriginalFileName の形式で添付ファイルが保存されます<\/LI><\/OL><\/LI>添付ファイルが既にディスク上に存在する場合は再度ダウンロードしません<\/LI>ダウンロードの概要(合計ダウンロード数と合計添付ファイルサイズ)が最終コンソール出力として提供されます<\/LI><\/OL><\/P>セットアップ方法は?<\/STRONG><\/P><\/P>ArcGIS API for Python の インストールとセットアップ<\/A> ガイドに従いますAnaconda を使用している場合は .yml ファイルで適切な環境を作成できます<\/LI><\/OL><\/LI>Startup.bat ファイルを使用している場合は(テキストエディタで)適切なフォルダー参照に編集します<\/LI>Jupyter Notebook が開いたら、下記の添付 .zip ファイルをアクセス可能な場所に貼り付け(解凍してください)ます<\/LI>Jupyter Notebooks で DownloadAttachments.ipynb ファイルを開き実行します(コード内クリック後 Ctrl+Enter 押下)<\/LI>スクリプトは指定された公開フィーチャ レイヤー上で動作し、指定された Downloads フォルダーへ添付ファイルをダウンロードします<\/LI>スクリプト実行時には Logging フォルダー内に関連ログ ファイルが作成されます<\/LI><\/OL><\/P>注意事項:<\/STRONG><\/P><\/P>FeatureLayerId 変数を更新してご自身のフィーチャ レイヤーで実行してください<\/LI>フィーチャ レイヤーがセキュアな場合は PortalUserName, PortalPassword を指定してください<\/LI>フォルダー名は 0-9 と a-Z の文字のみ表示されるようフィルターされています<\/LI>このスクリプトは ArcGIS Enterprise(ArcGIS Online にホストされたフィーチャ レイヤーのみ対象)ではテストされていませんが、それでも動作するはずです<\/LI>コードは Esri developer-support GitHub リポジトリ からも入手可能です<\/LI><\/UL><\/BODY><\/HTML>
このため、新しい
このスクリプトは何をするのか?<\/STRONG><\/P><\/P>フィーチャ 添付ファイルを保存するフォルダー(例:Attachment Downloads)を作成します<\/LI>このフォルダー内に指定されたフィーチャ レイヤーの各レイヤーごとにサブフォルダーを作成しますAttachmentStorage 変数が 'GroupedFolder<\/SPAN>' に設定されている場合、添付ファイルは ObjectId-AttachmentId-OriginalFileName の形式で単一フォルダー内に保存されます<\/LI>AttachmentStorage 変数が 'IndividualFolder' に設定されている場合、添付ファイルがある各フィーチャごとに新しいフォルダー(フィーチャの Object ID を名前として)を作成し、その中に AttachmentId-OriginalFileName の形式で添付ファイルが保存されます<\/LI><\/OL><\/LI>添付ファイルが既にディスク上に存在する場合は再度ダウンロードしません<\/LI>ダウンロードの概要(合計ダウンロード数と合計添付ファイルサイズ)が最終コンソール出力として提供されます<\/LI><\/OL><\/P>セットアップ方法は?<\/STRONG><\/P><\/P>ArcGIS API for Python の
注意事項:<\/STRONG><\/P><\/P>FeatureLayerId 変数を更新してご自身のフィーチャ レイヤーで実行してください<\/LI>フィーチャ レイヤーがセキュアな場合は PortalUserName, PortalPassword を指定してください<\/LI>フォルダー名は 0-9 と a-Z の文字のみ表示されるようフィルターされています<\/LI>このスクリプトは ArcGIS Enterprise(ArcGIS Online にホストされたフィーチャ レイヤーのみ対象)ではテストされていませんが、それでも動作するはずです<\/LI>コードは
Was anyone able to name the individual attachment folders by an attribute other than objectID? I've been struggling with this for awhile.
@DanielAragon1 @JoshVan_Vlack Did you ever figure out how to include in the image name a field form the feature layer?
DanielPérez_López
I'm getting this as well, the code is executing but the files don't seem to exist in the folder? Did you resolve this?
INFO:__main__:Summary: 28 new files have been downloaded totalling 19.588373MB in size INFO:__main__:Summary: 0 attachments already existed so were not downloaded again
Hey it always works so slowly or maybe i should run the code in other environment? Im using Jupyter Notebook and in 10 minutes only 7 photos got downloaded.
Awesome, thank you for sharing your script! After adding the "[0]'s" in row 123 and 137 it worked like a charm. I havent changed anything else yet for getting an attribute value for the folder names or anything else. Already happy with this step. Thanks again!
Hi Michael.
We used your script from time to time with great success.But lately it stops with an error.
Any ideas?
Thank you 🙂
Hi Michael, I'm hoping to use this script a lot, but I've got an error that's popping up and I'm not sure how to resolve it. I'm fairly new to Python, so I'm trying to learn as I go.
As when I look into that file, below is what it's showing. Any help with what I can do to fix it?
@tk060161 Since this is using the Python API, you would have to perform some sort of attribute query. You can run this in the ArcGIS Pro python window if you would like. In the highlighted code snippet, you would just need to construct a SQL query statement that mimics the selection you were making in ArcGIS Pro.
@MattAdamssnippet above shows how to get attachments based on an attribute field query. Is it possible to do this based on a selected feature in Pro?
Hello @LuanGaspar ,
Sorry for the late response, I have added another loop to repeat the downloads for all tables as well:
for itable in range(len(itemObject.tables)): # featureTable = itemObject.tables[itable]
Then you can repeat the same thing you do for the layers
Hello @Felicitychun ,
Did you improve the script to download attachments from related table too ? If so, could you share with us?
I'm look for way to export all attachments from the survey feature and repeats tables as well on a single script.
Hello,
Great script! I am just wondering if it is at all possible to modify the name of each individual folder based on an attribute within the layer?
Thanks!
@Felicitychun Thank you for your response! It seems that your suggestion resolved that error.
Now when I run the script, it seems to feed me back the code, and the file path I tried to feed the attachments in was empty.
I really appreciate any response! A newbie to python and trying to improve!
@MichaelKelly
Hi @Anonymous User
looks like 'false' there in your code is not in brackets as a string so is trying to refer to a variable that has not been defined. In python I believe the keyword for the boolean true/false is with a capital: False
Hi anyone interested, thought I'd post my solution to my question above,
I've gotten my parent global ids using this line:
featureGuIds = featureLayer.query(where=featureFilter,out_fields=['globalid','objectid'], as_df=True,return_geometry=False)
And then I could get it when I iterate through to get the attachments as well as the object id:
currentObjectId = featureGuIds['objectid'][j] parentGlobalId = featureGuIds['globalid'][j]
Hi,
So I got the Jupyter Notebook open, I saved the attachment, and went in to customize the code to my needs. Ran the code and got this error:
NameError Traceback (most recent call last)<ipython-input-2-17b343b15353> in <module>9 "start_time": "2017-08-16T09:06:05.091046Z"10 },---> 11 "scrolled": false12 },13 "outputs": [
NameError: name 'false' is not defined
I'm trying to figure this out in the mean time, but please let me know if you can help me.
Hi @MichaelKelly ,Thanks for this, it's great!
I'm wanting to build the attachment table at the same time to get the relationships so I need the parentGlobalID. Mine doesn't have that available though:
for k in range(len(currentObjectIdAttachments)): attachmentGlobalId = currentObjectIdAttachments[k]['globalId'] attachmentParentGlobalId = currentObjectIdAttachments[k]['parentGlobalId'] attachmentId = currentObjectIdAttachments[k]['id'] attachmentName = currentObjectIdAttachments[k]['name'] attachmentSize = currentObjectIdAttachments[k]['size']
and Global ID is 'globalid' instead of 'globalID'any pointers on how do we get it from the feature as we iterate through?
Cheers
You are a lifesaver!!!!! That worked perfectly. I had been trying to figure that out for hours.... Thank you so much!
Yes! I was able to do this by using the highlighted query.
Is there a way to only download some attachments based on an attribute field? I want to be able to put in a specific project name and just download the attachments from that project (so I'm downloading 20 attachments instead of 1500). I tried this for the query (ProjectName is an attribute in my feature layer):
featureObjectIds <SPAN class="" style="color: #a67f59; background: rgba(255, 255, 255, 0.5); border: 0px; font-weight: inherit;">=</SPAN> featureLayer<SPAN class="" style="color: #999999; border: 0px; font-weight: inherit;">.</SPAN>query<SPAN class="" style="color: #999999; border: 0px; font-weight: inherit;">(</SPAN>where<SPAN class="" style="color: #a67f59; background: rgba(255, 255, 255, 0.5); border: 0px; font-weight: inherit;">=ProjectName</SPAN><SPAN class="" style="color: #669900; border: 0px; font-weight: inherit;"> == <SPAN style="color: #333333; background-color: #f7f7f7;">'9858C</SPAN>'</SPAN><SPAN class="" style="color: #999999; border: 0px; font-weight: inherit;">,</SPAN> return_ids_only<SPAN class="" style="color: #a67f59; background: rgba(255, 255, 255, 0.5); border: 0px; font-weight: inherit;">=</SPAN><SPAN class="" style="color: #990000; border: 0px; font-weight: inherit;">True</SPAN><SPAN class="" style="color: #999999; border: 0px; font-weight: inherit;">)</SPAN>
But then I got this error:
NameError: name 'ProjectName' is not defined Is there any way to do this?
Try using a service Item ID that you are familiar with. Like one that is in your own AGOL organization do not try using the default Item ID. The error you are getting is basically saying it is not finding a feature service based on the ID you are giving it.
The weird thing is I am just running the script as I downloaded it so wondering if the service that was set up for testing has now been taken down? Have you gotten the script to run recently? Maybe there are other changes that have happened that are causing the script to fail?
You may not be calling the feature correctly, the message says you have no name attribute
AttributeError: 'NoneType' object has no attribute 'name'
This script looks promising but I not sure I am set up to run it properly... Currently I am Right clicking on the original "DownloadAttachments.py" and then running "Edit with IDLE (ArcGIS Pro)" then Run > Run Module. This is what I get:
Python 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 14:00:49) [MSC v.1915 64 bit (AMD64)] on win32Type "help", "copyright", "credits" or "license()" for more information.>>> ================== RESTART: C:\Temp\DownloadAttachments.py ==================INFO:__main__:Script Starting at 2020-06-09 18:11:08.674435ERROR:arcgis._impl.connection:Item does not exist or is inaccessible.Traceback (most recent call last): File "C:\Temp\DownloadAttachments.py", line 77, in <module> logger.info('Iterating through layers in Feature Layer "{}"'.format(itemObject.name))AttributeError: 'NoneType' object has no attribute 'name'
I have left all of the configuration stuff alone and was trying to just see if I could get the test data to work...
Any suggestions for a novice?
Hi, everybody.I followed the post to download the attached photos from a survey I generated (the photos are inside a table).I have also modified the script because I had the same problem as @Chelsea Rozek
I'm running the script inside the ArcGis Online Notebook.It doesn't give me any error and it seems to download the content. However I go to the path where the downloaded photos are supposed to be but the folder doesn't exist. Although the script is saying that the photos are downloaded.
INFO:__main__:Time: 2020-06-08 10:44:57.796204 INFO:__main__:Currently looping through feature attachments in layer 1 of 2: storing in folder named "0-foto" INFO:__main__:There are 386 features to iterate in this layer INFO:__main__:The size of the current attachment being downloaded is 1.17647MB ----------
INFO:__main__:C:\ScriptDownloads\\0-foto\\103/fotos-20200525-132307.jpg being renamed as C:\ScriptDownloads\\0-foto\\103\103-fotos-20200525-132307.jpg INFO:__main__:The size of the current attachment being downloaded is 1.69949MB
Any suggestions? Thanks
Michael Kelly Thanks for this script! I'm using it for a few applications and it works great! Recently I implemented a survey123 app that captures pictures in a repeat, and so images are attached to a related table. Can this script be modified to download attachments from related tables, or is does it need to be from the feature layer?
Hello Michael Kelly. Thank you fo putting script together and sharing it with the Community. I forked your project in Github. I'm working on adding capabilities the Community is requesting here and will submit a commit soon. Plus I am adding the ability to choose a portal that is Enterprise or AGO, and some other automation.
As for saving each attachment with a file name using an attribute value I am running into an issue with the FeatureSet object that is returned from Query() I am passing in the currentObjectId to obtain the field containing the pole number, which is esupportstructure_facilityid.
currentObjectId <SPAN class="operator token">=</SPAN> featureObjectIds<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'objectIds'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN>j<SPAN class="punctuation token">]</SPAN> facilityID <SPAN class="operator token">=</SPAN> featureLayer<SPAN class="punctuation token">.</SPAN>query<SPAN class="punctuation token">(</SPAN>objectids<SPAN class="operator token">=</SPAN>currentObjectId<SPAN class="punctuation token">,</SPAN> outFields<SPAN class="operator token">=</SPAN><SPAN class="string token">'esupportstructure_facilityid'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
The documentation appears to return a JSON object so I also tried treated it as such. When I do that another error appears as attached below,
FeatureSet' object is not subscriptable
I have not found any ArcGIS Python API examples that work with FeatureSet object and Query(), can you point to some samples or provide a snippet.
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-1-bc6c83cbc278> in <module> 202 currentObjectId = featureObjectIds['objectIds'][j] 203 facilityID = featureLayer.query(objectids=currentObjectId, outFields='esupportstructure_facilityid')--> 204 poleNumber = facilityID['eSupportStructure_FACILITYID'] 205 logger.info(f'{poleNumber}') 206 currentObjectIdAttachments = featureLayer.attachments.get_list(oid=currentObjectId)TypeError: 'FeatureSet' object is not subscriptable
JSON Response from Query().
INFO:__main__:{"features": [{"geometry": {"x": 2678790.012921214, "y": 236090.84788563848}, "attributes": {"eSupportStructure_FACILITYID": "47185"}}], "objectIdFieldName": "OBJECTID", "globalIdFieldName": "GlobalID", "spatialReference": {"wkid": 102660, "latestWkid": 2238}, "geometryType": "esriGeometryPoint", "fields": [{"name": "eSupportStructure_FACILITYID", "alias": "Pole Number", "type": "esriFieldTypeString", "length": 20}]}
this worked for me too (ie just adding [0] on line 123, and line 137, so that the line is
renameFile(currentAttachmentPath[0], newAttachmentPath)
instead of
renameFile(currentAttachmentPath, newAttachmentPath)
- I am running python 3.7.2, so it seems to be an issues that comes up when using a later version of python
Is the feature layer you're running this on publicly accessible? If yes, what's the url?
I did that step and this error popped up.
Sounds like Holly's error above, see my previous response for a solution: adding [0] to the end of the currentAttachmentPath variable
サインインしたメンバーは投稿、更新のフォローなどができます。初めてですか?無料アカウントを登録してください。
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.