Mantener los datos espaciales actualizados es un desafío común cuando se trabaja a gran escala, especialmente cuando los resultados analíticos deben publicarse continuamente de nuevo en los sistemas operativos. Con ArcGIS GeoAnalytics para Fabric, puedes escribir los resultados del análisis directamente en servicios de entidades. Al actualizar servicios de entidades, puede que no quieras reescribir todo con cada actualización. Usando la opción upsert, puedes actualizar entidades existentes y agregar nuevas en una sola operación eficiente. En esta publicación, veremos cómo upsert simplifica las actualizaciones incrementales a servicios de entidades, ayudándote a mantener capas autorizadas actuales mientras preservas IDs de entidades estables y apoyas aplicaciones y paneles posteriores.
En esta entrada del blog, recorreremos el proceso para hacer esto y mostrar cómo funciona. Para demostrarlo, crearemos un nuevo servicio de entidades, leeremos los datos de ese servicio, realizaremos una actualización en algunas filas y luego usaremos upsert para modificar solo esas filas en nuestro servicio guardado con los datos actualizados.
Crear un servicio de entidades
Para demostrar cómo funciona upsert, comenzaremos creando un servicio de entidades. Para mantenerlo simple, solo leeremos una capa de datos del Living Atlas of the World de Esri y la escribiremos en nuestra cuenta en ArcGIS Online. Este será nuestro servicio "nuevo" que actualizaremos.
Primero importamos la biblioteca GeoAnalytics para Fabric y las funciones Pyspark SQL
# imports
import geoanalytics_fabric
import pyspark.sql.functions as F
A continuación, leeremos un conjunto de datos de ciudades principales de EE.UU. para usar como ejemplo. En este caso, solo usaremos algunos atributos del servicio original del Living Atlas. Para este ejemplo, eliminaremos el campo OBJECTID que se genera automáticamente en un Servicio de Entidades y lo reemplazaremos con un campo llamado "My_ID." Esto se usa solo para mostrar la creación de un OBJECTID indexado único cuando escribimos nuestro nuevo servicio (de lo contrario terminaríamos con un segundo campo OBJECTID al escribirlo en el siguiente paso).
# leer un conjunto de datos para usar como ejemplo para upsert
# conjunto de ciudades principales de EE.UU. del ArcGIS Living Atlas of the World
myFS="https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Major_Cities_/FeatureServer/0"
myFSDataFrame = spark.read.format('feature-service').load(myFS)\
.select("OBJECTID", "NAME", "STATE_ABBR", "PLACE_FIPS", "SHAPE")\
.withColumn("My_ID", F.col("OBJECTID"))\
.drop("OBJECTID") # eliminar el campo OBJECTID original ya que usaremos My_ID como campo coincidente para upsert
display(myFSDataFrame)
Usando el DataFrame resultante como nuestro conjunto de datos de muestra, lo escribiremos en nuestra cuenta ArcGIS Online para tener un nuevo servicio que podamos editar.
Para hacer eso, conectamos a nuestra cuenta ArcGIS Online:
# registrar un gis donde escribiremos los datos - usando credenciales AGOL
geoanalytics_fabric.register_gis("myGIS", "https://arcgis.com", username="my_username", password="my_password")Luego escribimos el DataFrame en nuestra cuenta ArcGIS Online. Nota que al hacer esta escritura inicial, estamos configurando un upsertMatchingField. Esto especifica el campo de la capa que se usará para emparejar entidades con upsert. Podemos usar cualquier campo que tenga un índice único – y en este caso es "My_ID," un identificador único.
Cuando creamos nuestra nueva capa y especificamos el upsertMatchingField, se crea un índice único en nuestro campo especificado (My_ID).
# escribir a mi gis
# especificando que el campo "My_ID" será el campo upsert (crea índice único)
myFSDataFrame.write.format('feature-service')\
.option("gis", "myGIS")\
.option("serviceName", "us_cities_upsert_example_with_unique_index")\
.option("layerName", "layer")\
.option("upsertMatchingField", "My_ID")\
.save()Actualizar algunos datos
Podemos recuperar los datos desde esta capa para confirmar que el contenido es el esperado y luego identificar algunas filas que actualizaremos usando upsert. Nota que estamos especificando la opción para conectar a nuestra cuenta ArcGIS Online. Es importante asegurarse de haber registrado la cuenta ArcGIS Online donde viven tus datos para poder acceder a ellos tanto para lectura como escritura!
# leer nuestros datos del nuevo servicio - usaremos este DataFrame para demostrar la funcionalidad upsert
myNewFS = "https://your_service_URL"
myNewFSDataFrame = spark.read.format('feature-service')\
.option("gis", "myGIS")\
.load(myNewFS)
display(myNewFSDataFrame)

Nuestro nuevo servicio tiene todos nuestros campos originales, más un nuevo campo OBJECTID creado automáticamente al escribir el servicio.
Ahora veamos qué pasa cuando queremos actualizar un subconjunto de nuestros datos. Para simplificar, solo actualizaremos los registros con los dos primeros IDs – en otras palabras, reemplazaremos "Alabaster" por "New City 1" y "Albertville" por "New City 2":
# editar dos filas para actualizar
updated_row = myFSDataFrame.filter("My_ID in (1, 2)")\
.withColumn("NAME", F.when(F.col("My_ID") == 1, "New City Name 1").otherwise("New City Name 2"))
display(updated_row)
Si queremos actualizar nuestro servicio en ArcGIS Online con estos nuevos registros – pero solo actualizar estas dos filas - podemos usar upsert. Escribamos este DataFrame con solo las dos filas actualizadas nuevamente en nuestro servicio. Al escribir estos datos, establecemos el modo a "append" y especificamos nuestro upsertMatchingField como "My_ID." Esto hará coincidir los IDs únicos de esos registros e intercambiará los atributos solo para esas filas.
# escribir las filas actualizadas al servicio usando upsert
service_url = "https://your_service_URL"
updated_row.write.mode("append").format('feature-service')\
.option("gis", "myGIS")\
.option("serviceURL", service_url)\
.option("upsertMatchingField", "My_ID")\
.option("layerName", "layer")\
.save()Ahora podemos verificar que los cambios se aplicaron leyendo nuevamente nuestro servicio y observando los datos:
myfs_upsert_url = "https://your_service_URL"
myFSDataFrame_after_upsert = spark.read.format('feature-service')\
.option("gis", "myGIS")\
.load(myfs_upsert_url)
display(myFSDataFrame_after_upsert)

¡Y solo dos filas necesitaban ser actualizadas! Esto normalmente será más eficiente que sobrescribir toda la tabla.
Conclusión
¡Espero que esta haya sido una demostración útil sobre cómo puedes actualizar selectivamente servicios de entidades eficientemente usando GeoAnalytics para Fabric!