Repository navigation
Shared Metadata Tables
This guide explains how to use shared metadata tables in Azure Synapse Analytics to enable advanced data access scenarios for your Business Central data.
- Overview
- What are Shared Metadata Tables?
- Advantages
- Setup Requirements
- Configuration Steps
- Using Shared Metadata Tables
- Advanced Topics
Shared metadata tables provide an additional way to access your consolidated Business Central data in Azure Synapse Analytics, enabling:
- ✅ SQL queries via Serverless SQL pool
- ✅ Spark notebook processing
- ✅ Power BI DirectQuery connections
- ✅ Multi-table joins and complex queries
- ✅ No additional data storage (references existing Parquet files)
Note: This feature is only available for the Azure Data Lake Storage export option.
Azure Synapse Analytics allows different computational engines to share databases and tables:
- Apache Spark pools can create and manage tables
- Serverless SQL pool can query these same tables
- Tables are automatically synchronized between engines
- Data remains on the data lake (no duplication)
- Spark job creates a table from Parquet files
- Table metadata is registered in lake database
- Serverless SQL pool automatically discovers the table
- Both Spark and SQL can query the same table
- Data stays in data lake (no copying)
📖 Learn more about shared metadata
✅ Standard SQL syntax for familiar querying ✅ Serverless - no database compute costs ✅ Fast - optimized for analytics ✅ Familiar tools - use SQL Server Management Studio, Azure Data Studio, etc.
✅ DirectQuery support - real-time data access ✅ Import mode - for smaller datasets ✅ Multi-table models - join tables like a traditional database ✅ Similar to API entities - familiar data modeling patterns
📖 Connect Power BI to Serverless SQL
✅ Python, Scala, C#, or SQL notebooks ✅ Big data processing capabilities ✅ Machine learning integration ✅ Advanced transformations
✅ No database compute - data stays in lake ✅ Serverless SQL - pay per query ✅ Reduced storage - single copy of data ✅ Optimized format - Parquet compression
Before enabling shared metadata tables:
- ✅ Azure Data Lake Storage option configured (setup guide)
- ✅ Azure Synapse workspace with pipelines deployed
- ✅ Parquet format selected for CDM data format
- ✅ Apache Spark pool created in Synapse
-
Serverless Apache Spark pool
- Small compute size is sufficient
- Used only during table creation
- Auto-pauses when not in use
-
CreateParquetTable notebook
- Imported into Synapse workspace
- Located at:
synapse/notebook/CreateParquetTable.ipynb
-
Permissions
- Synapse workspace managed identity has Storage Blob Data Contributor role on data lake
- Open Azure Portal > Your Synapse workspace
- Navigate to Apache Spark pools
- Click + New
- Configure:
- Name: e.g., "sparkpool01"
- Node size: Small (4 vCores, 32 GB)
- Number of nodes: 3 (minimum)
- Autoscale: Enabled
- Automatic pausing: Enabled (15 minutes)
- Click Review + create > Create
- Open Synapse Studio
- Navigate to Develop tab
- Click + > Import
- Select the file:
synapse/notebook/CreateParquetTable.ipynb - The notebook appears in your workspace
- Click Publish all to save
The notebook runs using the Synapse workspace's managed identity, which needs read access to the data lake.
- Open Azure Portal > Your Storage Account (BC data)
- Navigate to Access Control (IAM)
- Click Add > Add role assignment
- Select role: Storage Blob Data Contributor
- Click Next
- Click Select members
- Search for your Synapse workspace name
- Select it (this is the managed identity)
- Click Select > Review + assign
Note: The managed identity has the same name as your Synapse workspace.
- Open Export to Azure Data Lake Storage page in BC
- Ensure CDM data format is set to Parquet
- This is required - CSV format is not supported for shared metadata tables
When executing the Consolidation_AllEntities pipeline:
- Open Synapse Studio > Integrate > Consolidation_AllEntities
- Click Add trigger > Trigger now
- Provide parameters:
- containerName: Your container (e.g., "businesscentral")
- deleteDeltas: true or false
- sparkpoolName: Your Spark pool name (e.g., "sparkpool01")
- Click OK
Important: If sparkpoolName is blank, the pipeline runs but no shared metadata tables are created.
After successful pipeline execution:
- Open Synapse Studio
- Navigate to Data tab (database icon)
- Expand Lake databases
- Find database named after your container (in lowercase)
- Expand Tables to see all exported entities

Naming conventions:
- Database name: Container name in lowercase
- Table names: Table names in lowercase
- Non-alphanumeric characters (e.g.,
-) become underscores (_)
- Right-click a table
- Select New SQL script > Select TOP 100 rows
- Script generates automatically
- Click Run to execute
SELECT TOP 100 *
FROM [businesscentral].[customer]- Open Azure Data Studio or SQL Server Management Studio
- Connect to Serverless SQL endpoint:
- Server:
<workspace-name>-ondemand.sql.azuresynapse.net - Authentication: Azure Active Directory
- Server:
- Select database (your container name)
- Query tables:
-- Query customer data
SELECT
No_ AS CustomerNo,
Name,
City,
Country_Region_Code
FROM [businesscentral].[customer]
WHERE Country_Region_Code = 'US'-- Join customers with sales orders
SELECT
c.No_ AS CustomerNo,
c.Name AS CustomerName,
s.No_ AS OrderNo,
s.Order_Date,
s.Amount
FROM [businesscentral].[customer] c
INNER JOIN [businesscentral].[sales_header] s
ON c.No_ = s.Sell_to_Customer_No_
WHERE s.Order_Date >= '2024-01-01'- Open Power BI Desktop
- Click Get Data > Azure > Azure Synapse Analytics SQL
- Configure connection:
-
Server:
<workspace-name>-ondemand.sql.azuresynapse.net - Database: Your container name (e.g., "businesscentral")
- Data Connectivity mode: DirectQuery
-
Server:
- Click OK
- Select tables to include
- Build your report
Advantages of DirectQuery:
- Always shows latest data
- No data refresh needed
- Suitable for large datasets
- Queries execute on-demand
- Follow same steps as DirectQuery
- Select Import as Data Connectivity mode
- Data is loaded into Power BI model
- Schedule refreshes in Power BI Service
Advantages of Import:
- Faster report performance
- Offline access
- More DAX capabilities
- Smaller datasets
# Read table into Spark DataFrame
df = spark.read.table("businesscentral.customer")
# Show first 10 rows
df.show(10)
# Filter and aggregate
df_filtered = df.filter(df.Country_Region_Code == "US")
df_grouped = df_filtered.groupBy("City").count()
df_grouped.show()// Read table
val df = spark.read.table("businesscentral.customer")
// Show schema
df.printSchema()
// Run query
df.filter($"Country_Region_Code" === "US")
.groupBy("City")
.count()
.show()%%sql
SELECT
City,
COUNT(*) as CustomerCount
FROM businesscentral.customer
WHERE Country_Region_Code = 'US'
GROUP BY City
ORDER BY CustomerCount DESCWhen BC table schema changes (add/remove fields):
Problem: Shared metadata table schema becomes out of sync
Solution:
-
Drop the table (via Spark notebook or SQL):
DROP TABLE IF EXISTS businesscentral.customer;
-
Re-run consolidation pipeline with sparkpoolName
-
Table is recreated with new schema
If you already have data exported before enabling shared metadata tables:
Problem: Notebook only runs for new tables, not existing ones
Solutions:
Option 1: Trigger notebook manually
- Open CreateParquetTable notebook in Synapse Studio
- Set parameters:
- container_name: Your container
- entity_name: Table name to create
- Attach Spark pool
- Configure session: Run as managed identity = Enabled
- Run the notebook
- Repeat for each existing table
Option 2: Modify pipeline logic
- Edit Consolidation_OneEntity pipeline
- Find SparkTableConditions activity
- Modify condition to trigger notebook for existing tables
- Republish pipeline
For very large tables, consider partitioning:
# Create partitioned table
df = spark.read.parquet("abfss://container@storage.dfs.core.windows.net/data/Customer/*.parquet")
df.write.partitionBy("Country_Region_Code").saveAsTable("businesscentral.customer")Collect statistics for query optimization:
-- Analyze table
ANALYZE TABLE businesscentral.customer COMPUTE STATISTICS;Implement in views for fine-grained access:
CREATE VIEW businesscentral.customer_secure AS
SELECT *
FROM businesscentral.customer
WHERE Country_Region_Code IN (
SELECT CountryCode FROM user_permissions WHERE UserID = USER_NAME()
)Create views with limited columns:
CREATE VIEW businesscentral.customer_public AS
SELECT
No_,
Name,
City,
Country_Region_Code
FROM businesscentral.customer
-- Exclude sensitive fieldsProblem: Pipeline succeeds but no table in lake database
Checks:
- ✅ Verify sparkpoolName parameter was provided
- ✅ Ensure CDM format is Parquet (not CSV)
- ✅ Check Spark pool is running
- ✅ Review pipeline activity logs for notebook execution
- ✅ Verify managed identity has data lake permissions
Problem: "Access denied" when notebook runs
Solutions:
- ✅ Grant Storage Blob Data Contributor to workspace managed identity
- ✅ Verify role assignment on correct storage account
- ✅ Check managed identity is enabled on Synapse workspace
Problem: Table columns don't match current BC table
Solution:
- Drop and recreate table (see Schema Changes above)
Problem: Slow SQL queries
Solutions:
- ✅ Ensure Parquet format is used (better than CSV)
- ✅ Add WHERE clauses to filter data
- ✅ Use appropriate indexes in views
- ✅ Consider partitioning large tables
- ✅ Collect statistics
✅ Always use Parquet format for shared metadata tables ✅ Grant minimum permissions to managed identity ✅ Drop and recreate tables when schema changes ✅ Use views for security and simplified access ✅ Monitor Spark pool costs - enable auto-pause ✅ Test queries in Synapse Studio before using in Power BI ✅ Document table naming conventions for your team
Shared metadata tables provide:
- ✅ SQL access to BC data without database compute
- ✅ Power BI DirectQuery for real-time reporting
- ✅ Spark analytics for advanced scenarios
- ✅ Single source of truth (no data duplication)
- ✅ Cost-efficient data access
Next Steps:
- Create Spark pool if not already done
- Import CreateParquetTable notebook
- Grant permissions to managed identity
- Run pipeline with sparkpoolName parameter
- Connect Power BI or query with SQL
- Build reports and analytics
Related: Azure Data Lake Setup | Execution Guide | FAQs | Back to Home