Databases and apps on SharePoint data
Building an application read replica or a document catalogue in Postgres, Supabase or another database, with a normalised schema an app can query directly.
A team keeps its supplier records in a SharePoint list and has been asked for a small web app over the same data. The first version calls Microsoft Graph directly. It works in testing, then starts backing off from throttling responses once real users arrive, and every column has to be translated from SharePoint's field types before the app can use it.
What the app wants is a database. With a replica in PostgreSQL, Supabase, MySQL, MariaDB or SQLite, it reads tables with typed columns and whatever indexes you add. A lookup becomes a key column you can join on, a multi-value column becomes a child table keyed on sp_item_id, and people sit in one shared sp_users table. The app, or an API in front of it, queries that copy as it would any other database, with no SharePoint code in it at all.
People keep editing in SharePoint. The replica catches up on a schedule, every five minutes by default, by reading only the items that changed since the last run, so the app never calls Graph and never competes with other integrations for the tenant's throttling budget. When someone adds a column to the list, the column appears in the table on the next run. A removed column stays, so nothing the app reads disappears, and on PostgreSQL, MySQL, MariaDB and SQLite a column whose type changes gets a _v2 column beside the old one.
The replica only goes one way. SPSync reads from SharePoint and writes to the database, and nothing flows back. An app that needs to change a SharePoint item keeps doing that through its own Graph call, or keeps its own data in its own tables. Write-back is designed on the two-way sync roadmap page and has not shipped. SharePoint item permissions are not copied either, so who can read which rows comes down to the database roles and row-level security you grant.
Each post here takes one destination and one team, from a Supabase client portal to an offline SQLite file a caseworker carries on a laptop. They share one schema, so what you learn on one destination carries over to the next.
Start here
- SharePoint lists in PostgreSQL, ready for Metabase and apps
PostgreSQL comes first because it shows the table shape every other destination in this topic shares.
- A client portal on Supabase, fed from SharePoint lists
Supabase puts an app on those same tables, with its table editor, REST API and Realtime.
- An offline SQLite copy of SharePoint lists for caseworkers
The SQLite post is for a copy that has to work offline, in one file on a laptop.
- SharePoint to MySQL or MariaDB for a Grafana defects board
MySQL and MariaDB come last, for teams that already run one of them and chart it in Grafana.
All posts on this topic
- SharePoint document library metadata in SQL Server, with folders and content types
You need a report of every document in a library: its content type, folder, owner and missing fields. How library metadata arrives in SQL, row by row, and what to check.
- Microsoft Lists to SQL Server: a Lists app list is a SharePoint list underneath
You built a tracker in Microsoft Lists and now it has to reach SQL Server. Where the list lives decides the route: team site lists replicate like any SharePoint list.
- Power Apps on SharePoint past the row limit: when to use SQL
Why a Power Apps gallery on a large SharePoint list misses rows, what SharePoint can and cannot delegate, and when the app's read screens belong on SQL.
- Querying a SharePoint list with SQL: four routes compared
An analyst wants one SELECT against a SharePoint list and a join to the finance database. Drivers, linked servers, the content database and a copy, weighed.
- SharePoint as a database: where a list stops being one
What a SharePoint list does well as a database, the limits it runs into, a decision table, and the options from Dataverse to a SQL copy you report from.
- SharePoint list to Oracle Database for an APEX report and a PL/SQL job
Your APEX report and a nightly PL/SQL job need a SharePoint list as Oracle tables. How to set up the two Oracle users, what the tables look like, and how the copy stays current.
- SharePoint to MySQL or MariaDB for a Grafana defects board
Ashcroft Build Group's defects, projects and subcontractor lists copied from SharePoint into MySQL or MariaDB, then charted in Grafana by site.
- SharePoint lists in PostgreSQL, ready for Metabase and apps
A retail walkthrough: three SharePoint lists replicated into PostgreSQL, with joinable lookups, child tables and a Metabase dashboard on top.
- An offline SQLite copy of SharePoint lists for caseworkers
Riverside Borough Council's FOI, enquiry and councillor lists kept in one SQLite file that a caseworker can query on a laptop without a connection.
- A client portal on Supabase, fed from SharePoint lists
A law firm's matters, clients and conflicts lists replicated into Supabase Postgres, ready for the table editor, the generated REST API and Realtime.
Other topics on the blog
Frequently asked questions
Why not just call the Graph API from the application directly?
It works for low-volume, occasional reads. It gets fragile once an application depends on it continuously: Graph throttling responses need handling, lookup and person columns need resolving on every call, and any schema change on the list can change the shape of what the API returns without warning.
Does the application ever write back through SPSync?
SPSync only reads from SharePoint and writes to the destination database. An application that needs to write to SharePoint keeps doing so through its own Graph calls.
How does this handle a list's schema changing over time?
New columns are added automatically and removed columns stay, so no data is dropped. On SQL Server, PostgreSQL, MySQL, ClickHouse, Oracle, SQLite and DuckDB, a retyped column gets a versioned column beside the old one, so an application reading the table keeps working through an unexpected change. Other destinations do not fork a retyped column this way today.