Hi everyone,
I’m looking for some data flow advice on the most efficient and robust way to update registered Enterprise Geodatabase tables (hosted in SQL Server) from a weekly CSV data drop.
The Context:
Each week, I receive a large data drop (80+ CSVs). These CSVs represent the complete and current state of the data. Because it's a full state drop, the synchronization process needs to handle inserts for new records, updates for changed records, and importantly, deletes for records that exist in the database but are no longer present in the incoming CSV. My goal is to mirror this data into non-spatial tables that are registered with our Enterprise Geodatabase. There will be no intention or need to update these tables other than during the weekly mirror process.
What We’ve Tried:
We initially built a custom, high-performance ETL pipeline using Python. Our workflow looked like this:
Used DuckDB to extract and filter the CSVs directly from disk into memory-efficient chunks.
Formatted the data into standard Python tuples.
Used pyodbc to load the data into a temporary #Staging table in SQL Server.
Executed a raw T-SQL MERGE statement to upsert the data and delete missing rows, explicitly ignoring Esri-managed fields like OBJECTID and GlobalID so we wouldn't overwrite them.
The Problem:
After testing, it became clear that performing raw SQL operations into an Esri-registered table is problematic. Bypassing the ArcGIS application tier to perform these upserts and deletes seems to not play nice with underlying Geodatabase mechanics (presumably related to how SDE manages IDs, indexes, versioning, or archiving). It seems that ESRI-managed tables are best managed by Esri tools to account for all these intricacies.
Potential Approaches:
If I have a CSV representing the absolute current state of a table, how best can I mirror that to a registered enterprise geodatabase table programmatically? I've been weighing a few different paths:
ArcGIS API for Python (Portal REST Endpoints): Bypassing the direct database connection entirely and using the arcgis library to interact with the published table's REST endpoint. Calculating the deltas in memory and passing them as adds, updates, and deletes via edit_features(). Does this application-tier approach perform well at scale compared to local arcpy operations?
Truncate and Load: Would truncating the table and simply appending the new CSV be the safest way to inherently handle the deletes? My concern here is whether this breaks existing relationship classes, web map pop-ups, or GlobalID dependencies downstream since the underlying IDs would constantly regenerate.
arcpy.management.Append with the upsert parameter: This seems great for the inserts and updates, but it doesn't natively handle deleting the records that have dropped off the source CSV.
arcpy.da Cursors: Relying on an UpdateCursor/InsertCursor script comparing dictionaries to calculate the delta and process the inserts, updates, and deletes row-by-row. Is this too slow for hundreds of thousands of rows?
Has anyone built a reliable, programmatically scheduled pipeline for this exact scenario? Any advice on which Esri tools, APIs, or Python libraries yield the most stable results for a true mirror (handling deletes safely) would be hugely appreciated!
Thanks in advance!