以前、フィーチャクラスを参照し、truncate/appendメソッドを使用してArcGIS Onlineのフィーチャサービスを上書きする方法についてドキュメントを書きました。多くのフィードバックをいただき、その中には添付ファイルがサポートされていない、複数レイヤーを含むサービスの更新に制限があるなどの問題がありました。このソリューションはこれらの制限に対応することを目的としています。以下はArcGIS Pro projectを参照してArcGIS Online feature serviceを上書きするスクリプトと、その使い方のビデオです。問題や質問があれば下にコメントしてください。
import arcpy, os, time, requests, json
from arcgis.gis import GIS
from arcgis.features import FeatureLayerCollection
# 変数
prjPath = r"C:\Projects\GeoNET\GeoNET.aprx" # Pro Projectへのパス
map = 'State Parks' # Pro Project内のマップ名
serviceDefID = '3fa1620c47dc490db43b9370e8cf5df8' # サービス定義のアイテムID
featureServiceID = 'fb42ef7b43154f95b8b6ad7357b7f663' # フィーチャサービスのアイテムID
portal = "https://www.arcgis.com" # AGOL
user = "jskinner_rats" # AGOLユーザー名
password = "********" # AGOLパスワード
preserveEditorTracking = True # フィーチャクラスから編集者トラッキングを保持するかどうか(True/False)
unregisterReplicas = True # 既存のレプリカ登録解除(True/False)
# 環境変数設定
arcpy.env.overwriteOutput = 1
# 警告無効化
requests.packages.urllib3.disable_warnings()
# タイマー開始
startTime = time.time()
print(f"AGOLに接続中")
gis = GIS(portal, user, password)
arcpy.SignInToPortal(portal, user, password)
# 一時コンテンツ作成用ローカルパス
sddraft = os.path.join(arcpy.env.scratchFolder, "WebUpdate.sddraft")
sd = os.path.join(arcpy.env.scratchFolder, "WebUpdate.sd")
sdItem = gis.content.get(serviceDefID)
# 新しいSDDraft作成およびSDへのステージング
print("SDファイル作成中")
arcpy.env.overwriteOutput = True
prj = arcpy.mp.ArcGISProject(prjPath)
mp = prj.listMaps(map)[0]
serviceDefName = sdItem.title
arcpy.mp.CreateWebLayerSDDraft(mp, sddraft, serviceDefName, 'MY_HOSTED_SERVICES',
'FEATURE_ACCESS', '', True, True)
arcpy.StageService_server(sddraft, sd)
# 既存フィーチャサービス参照でプロパティ取得
fsItem = gis.content.get(featureServiceID)
flyrCollection = FeatureLayerCollection.fromitem(fsItem)
properties = fsItem.get_data()
capabilities = flyrCollection.manager.properties
# サムネイルとメタデータ取得
thumbnail_file = fsItem.download_thumbnail(arcpy.env.scratchFolder)
metadata_file = fsItem.download_metadata(arcpy.env.scratchFolder)
# 既存レプリカ登録解除
enableSync = False
if unregisterReplicas:
if flyrCollection.properties.syncEnabled:
enableSync = True
print("既存レプリカ登録解除中")
for replica in flyrCollection.replicas.get_list():
replicaID = replica['replicaID']
flyrCollection.replicas.unregister(replicaID)
# フィーチャサービス上書き
sdItem.update(data=sd)
print("既存フィーチャサービスを上書き中")
if preserveEditorTracking:
pub_params = {"editorTrackingInfo" : {"preserveEditUsersAndTimestamps":'true'}}
fs = sdItem.publish(overwrite=True, publish_parameters=pub_params)
else:
fs = sdItem.publish(overwrite=True)
# 前のプロパティでサービス更新
print("サービスプロパティ更新中")
item_properties = {"text": json.dumps(properties)}
fs.update(item_properties=item_properties)
flyrCollection.manager.update_definition(capabilities)
# サムネイルとメタデータ更新
print("サムネイルとメタデータ更新中")
fs.update(thumbnail=thumbnail_file, metadata=metadata_file)
print("スクラッチディレクトリをクリア中")
arcpy.env.workspace = arcpy.env.scratchFolder
for file in arcpy.ListFiles():
if file.split(".")[-1] in ('sd', 'sddraft', 'png', 'xml'):
arcpy.Delete_management(file)
endTime = time.time()
elapsedTime = round((endTime - startTime) / 60, 2)
print(f"スクリプトは{elapsedTime}分で完了しました")
更新情報
2024年2月2日更新:既存レプリカ登録解除オプションを追加
2024年12月2日更新:以前有効だった場合、同期が再度有効化されるように変更