Synapse Migration
MicrosoftOfficialPublished by Microsoft
- Skill
- Workflow
- Software development
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The synapse-migration skill provides a structured, phased workflow for transitioning Synapse Analytics workspaces to Microsoft Fabric. It covers the migration of Spark items, Lake Databases, Linked Services, and Dedicated SQL Pool schema and stored procedures. The skill emphasizes a dependency-ordered approach, requiring gap assessment and explicit approval before conversion. It distinguishes between migrating to a Fabric Lakehouse (schema and code only, no data movement) and a Fabric Warehouse, while providing specific routing for dependent pipeline callers.
What it does
- Discovers and classifies Synapse workspace artifacts.
- Converts Dedicated SQL Pool schema and stored procedures to Spark SQL notebooks or Warehouse objects.
- Migrates Spark items, including notebooks and Spark Job Definitions, to Fabric equivalents.
- Maps Linked Services to Fabric Data Connections or OneLake Shortcuts.
- Manages the migration of approved dependent pipeline callers.
- Validates persisted definitions and artifacts against established contracts.
When to use it
- When migrating a full Synapse workspace to Microsoft Fabric.
- When converting Dedicated SQL Pool schema and procedures to a Lakehouse or Warehouse.
- When porting Spark pools, notebooks, or Spark Job Definitions to Fabric.
- When replacing Synapse Linked Services with Fabric-native connectivity.
Advantages
- Ensures dependency-ordered migration to maintain system integrity.
- Provides clear routing for different workload types (Lakehouse vs. Warehouse).
- Enforces strict validation and approval gates for behavior-changing decisions.
- Supports incremental migration rather than high-risk big-bang cutovers.
- Standardizes the conversion of T-SQL procedures to executable Spark SQL notebooks.
Usage examples
- “Migrate this Dedicated SQL Pool DACPAC to a Fabric Lakehouse and convert the procedures.”
- The agent will assess gaps, obtain approval for procedure-to-notebook mappings, create a migration manifest, convert schema/code artifacts, and validate the results.
- “Migrate this Dedicated SQL Pool to Fabric Warehouse.”
- The agent will assess DDL compatibility, remove unsupported distribution/index declarations, obtain provisioning consent, and prepare for potential data migration.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/microsoft/synapse-migration/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip synapse-migration.zip -d .agents/skills
Documentation by Microsoft
Telemetry — MANDATORY. Every
api.fabric.microsoft.comcall must carryx-ms-fabric-skill: synapse-migration(az rest:--headers "x-ms-fabric-skill=synapse-migration"), including every LRO poll,fabric_lroand retry. Snippets omit it — add it anyway.
OFFLINE LAKEHOUSE ARTIFACT FAST PATH — DECIDE FIRST. For a no-live-call request with complete supplied inputs and contracts, load only the fast path; do not load
migration-planning-reference.md,dedicated-pool-conversion.md, or implementation scripts. Use one generator for artifacts and final-byte hashes, then one verifier. Do not inspect generated files or run post-pass spot checks. For every optional non-null source default, setmissingValueBehaviortoUseSourceDefaultand restore that default before validation. Do not use this path for a Warehouse target; incomplete and large-procedure requests use their own routes.
CRITICAL NOTES
To find workspace details (including its ID) from a workspace name: list all workspaces, then use JMESPath filtering.
To find item details (including its ID) from workspace ID, item type, and item name: list all items of that type in that workspace, then use JMESPath filtering.
Treat a source Dedicated SQL Pool as read-only. Do not run source DDL, DML, stored procedures, or create sample objects.
Dedicated Pool-to-Lakehouse data movement is out of scope. Migrate schema and executable code artifacts only; do not copy source rows or run row-level/business-result equivalence queries. The separate Warehouse route may move data only from a separately approved restored export copy under its own consent gate and restored-source contract.
For Dedicated Pool-to-Lakehouse requests, complete gap assessment, explicit mapping approval, manifest creation, conversion, deployment, and validation in order. Read dedicated-pool-to-lakehouse.md once as the router, then load only the current phase reference.
Stored-procedure
1:1,N:1, andN:Nmappings never apply to views. Views remain schema objects; procedures become traceable Spark SQL notebooks with executable%%sqltransformation cells.Dependent ADF/Synapse callers are conditional scope, not automatic scope. Discover them during assessment, require a separate complete-closure approval, and migrate them only after notebook readiness. Route standalone pipeline requests to
pipeline-migration.Before executing a specialized Dedicated Pool workflow, read the matching contract in dedicated-pool-execution-contracts.md. Its validation, hashing, request-body, resume, and completion-language requirements are mandatory.
Keep Lakehouse and Warehouse paths separate. If the target is unclear, ask before loading path-specific resources. Lakehouse conversion never moves source rows; Warehouse data migration requires its own explicit consent gate and restored-source contract.
For a Fabric Warehouse target, explicitly state that the complete
DISTRIBUTIONandCLUSTERED COLUMNSTORE INDEXdeclarations are removed because Fabric manages distribution, storage, and indexing; a bare mention of either source clause is insufficient.Run setup DDL and CETAS only against the separately approved restored export copy after proving it is not the original production source.
Synapse Analytics to Microsoft Fabric Migration
Core Workflow
Discover the Synapse workspace and classify every source artifact.
Choose targets using workload-routing.md.
Assess gaps before conversion, including runtime, library, connectivity, T-SQL, security, and capacity constraints.
Obtain approval for behavior-changing decisions, target placement, and every stored-procedure-to-notebook mapping.
Create or update
migration-manifest.jsonand persist approval, per-object status, hashes, and checkpoints atomically.Convert and deploy in dependency order, loading only the current phase resource.
Validate persisted definitions and artifacts without executing generated notebooks or pipelines unless a separately approved workflow explicitly requires execution.
Report completed, blocked, skipped, and pending objects without exposing credentials or sensitive values.
For full-workspace orchestration, read migration-orchestrator.md. For a Dedicated Pool-to-Lakehouse migration, use dedicated-pool-to-lakehouse.md as the phase router. For a Warehouse target, load only the matching dw-* resource.
Scope Routing
| Request | Action | Load |
|---|---|---|
| Full Synapse workspace migration | Run phased discovery and migration | migration-orchestrator.md |
| Dedicated SQL Pool schema/code to Lakehouse | Run the strict assessment-to-validation workflow. For guidance-only notebook publication, explicitly state: "The stored procedures were converted from T-SQL to Spark SQL before publication." | dedicated-pool-to-lakehouse.md |
| Guidance-only Dedicated Pool incremental deployment hardening | Answer directly from the focused checklist; do not search scripts or load phase resources. State: "For columns with special characters, enable Delta columnMapping selectively and only with approval." | dedicated-pool-execution-contracts.md |
| Large or complex stored procedure | For a complete offline contract, read only the audit resource once, use one run-local generator and one verifier, do not inspect implementation scripts or generated outputs, and stop after successful verification | dedicated-pool-large-procedure-audit.md |
| Spark pool | Convert configuration and libraries to a Fabric Environment | spark-pool-migration.md |
| Lake Database or HMS | Create or bind the target Lakehouse | lake-database-migration.md or external-hms-migration.md |
| Notebook or Spark Job Definition | Port code, bindings, parameters, and runtime settings | spark-item-migration.md |
| Linked Service | Choose a Fabric Data Connection for external services or a OneLake Shortcut for ADLS Gen2/Blob | connectivity-migration.md |
| Approved dependent procedure callers | Run the internal closure-preserving sub-flow after notebook readback | dedicated-pool-dependent-pipelines.md |
| Standalone pipeline migration | Delegate | pipeline-migration |
| Dedicated SQL Pool to Fabric Warehouse | Run the source extraction, DDL compatibility, approval, optional data, security, and validation route | dw-source-and-extraction.md, then the matching dw-* phase resource |
| Standalone Fabric Warehouse administration | Delegate | sqldw-cli |
| Synapse Link | Use Fabric Mirroring; not covered here | — |
Always report the Lake Database/HMS phase. If none is discovered, mark it NotApplicable (none discovered) while retaining the required target Lakehouse binding.
Load References On Demand
Do not preload all files. Load only the references needed for the current phase:
| Need | Reference |
|---|---|
| Routing, phase order, API audiences, quick examples, troubleshooting, or post-migration handoff | workload-routing.md |
| Dedicated Pool execution variants and response contracts | dedicated-pool-execution-contracts.md |
| Dedicated Pool discovery | dedicated-pool-discovery.md |
| Gap assessment and mapping approval | dedicated-pool-gap-assessment.md |
| Procedure conversion and notebook shape | dedicated-pool-conversion.md |
| Schema/notebook deployment | dedicated-pool-deployment.md |
| Dedicated Pool validation | dedicated-pool-validation.md |
| Runtime/library compatibility | feature-parity.md and library-compatibility.md |
mssparkutils and connector refactoring | utility-api-mapping.md, connector-refactoring.md, and code-patterns.md |
| Capacity planning | capacity-sizing.md |
| Dedicated Pool-to-Warehouse source discovery and extraction | dw-source-and-extraction.md |
| Warehouse DDL compatibility and deployment | dw-ddl-compatibility.md |
| Separately approved Warehouse data migration | dw-data-migration.md |
| Warehouse security and validation | dw-security-validation.md |
| Validation, reporting, and production readiness | validation-testing.md, migration-report.md, and security-governance.md |
Use COMMON-CLI.md only for shared authentication and az rest mechanics not already covered by the phase resource. Use COMMON-CORE.md only for shared Fabric REST patterns.
Must
Preserve every stored-procedure input contract, source default, source decision, and approved target mapping.
Block conversion until gap dispositions, notebook names, dependency grouping, and target workspace placement are explicitly approved.
Use SqlPackage/DMVs for source discovery, Fabric REST for item management, and Fabric Livy statements for Lakehouse schema and Delta execution.
Run the maintained validators required by the selected execution contract; never replace them with ad hoc JSON or cell-shape checks.
Choose the Lakehouse or Warehouse target before loading implementation resources; never apply Warehouse data-movement rules to Lakehouse artifact conversion.
Before persisting any dependent-pipeline source definition, recursively inspect it for secret-bearing or uncertain properties; block the complete selected closure without writing the artifact or mutating a target when any are found.
In every dependent-pipeline response, including guidance-only and pre-approval explanations, state: "Use a
TridentNotebookactivity with exact target identitiestypeProperties.notebookIdandtypeProperties.workspaceId, and pass inputs throughtypeProperties.notebookParameters." Then state: "After deployment, read back each pipeline withPOST /v1/workspaces/{workspaceId}/items/{dataPipelineId}/getDefinitionand validate its canonical hash and structural bindings."For every Linked Service response, first state both replacement classes: Fabric Data Connections for external databases/services and OneLake Shortcuts for ADLS Gen2/Blob storage; then identify which class applies.
Replace
mssparkutilswithnotebookutils, Linked Services with the correct Fabric connection class, andspark.read.synapsesql()with a supported OneLake or JDBC pattern.Externalize workspace and item IDs through parameters or Variable Libraries.
Keep phase status concise, emit bounded heartbeats for long operations, and persist per-object evidence in the manifest.
Prefer
OneLake Shortcuts over copying data.
Fabric Environments for reproducible libraries and Spark settings.
Incremental, dependency-ordered migration over big-bang cutover.
Parameterized notebooks and Variable Libraries for environment promotion.
Lakehouse SQL Endpoint for compatible Serverless SQL Pool read workloads.
Avoid
Do not execute generated notebooks or pipelines as part of artifact migration.
Do not broaden a selected dependent-pipeline closure or route that internal sub-flow to
pipeline-migration.Do not use
sqlcmdagainst the target Fabric Warehouse; use the registered SQL endpoint tooling required by the Warehouse resource.Do not preserve Synapse distribution/storage hints, PolyBase DDL, Linked Service connection strings, or pool-level library installation patterns verbatim.
Do not use target notebooks to orchestrate the migration itself.
Do not hardcode workspace IDs, item IDs, credentials, connection strings, or environment-specific paths.
Examples
Prompt: "Migrate this Dedicated SQL Pool DACPAC to a Fabric Lakehouse and convert the procedures."
Response behavior: Assess gaps first, present and obtain approval for the complete procedure-to-notebook mapping and workspace placement, create the manifest, convert approved schema/code artifacts without moving source rows, validate persisted definitions, and report the resolved Lakehouse and artifact evidence.
Prompt: "Migrate this ADF pipeline to Fabric."
Response behavior: Route to pipeline-migration. Keep it here only when the pipeline is an explicitly approved dependent caller discovered inside an active Dedicated Pool-to-Lakehouse migration.
Prompt: "Migrate this Dedicated SQL Pool to Fabric Warehouse."
Response behavior: Keep this inside synapse-migration, assess DDL compatibility, remove unsupported distribution and columnstore declarations, obtain provisioning consent, and ask separately before any restored-source data migration.
For code transformations and edge cases, load workload-routing.md and the phase-specific resource rather than expanding the main instructions.
Files
- ATTRIBUTION.mdAdded by AutoGineer879 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md14.3 KiB
- apm.yml597 B
- references/dedicated-pool-execution-contracts.md14.5 KiB
- references/workload-routing.md6.0 KiB
- resources/capacity-sizing.md4.1 KiB
- resources/code-patterns.md8.4 KiB
- resources/connectivity-migration.md6.4 KiB
- resources/connector-refactoring.md13.8 KiB
- resources/dedicated-pool-conversion.md39.2 KiB
- resources/dedicated-pool-dependent-pipelines.md23.3 KiB
- resources/dedicated-pool-deployment.md20.0 KiB
- resources/dedicated-pool-discovery.md17.8 KiB
- resources/dedicated-pool-gap-assessment.md17.4 KiB
- resources/dedicated-pool-large-procedure-audit.md24.5 KiB
- resources/dedicated-pool-to-lakehouse.md17.9 KiB
- resources/dedicated-pool-validation.md17.2 KiB
- resources/dw-data-migration.md13.7 KiB
- resources/dw-ddl-compatibility.md9.4 KiB
- resources/dw-security-validation.md15.6 KiB
- resources/dw-source-and-extraction.md8.0 KiB
- resources/external-hms-migration.md20.2 KiB
- resources/feature-parity.md5.4 KiB
- resources/lake-database-migration.md34.8 KiB
- resources/library-compatibility.md7.2 KiB
- resources/migration-gotchas.md16.1 KiB
- resources/migration-orchestrator.md63.0 KiB
- resources/migration-planning-reference.md16.3 KiB
- resources/migration-report.md16.9 KiB
- resources/security-governance.md47.4 KiB
- resources/spark-item-migration.md19.2 KiB
- resources/spark-pool-migration.md16.3 KiB
- resources/utility-api-mapping.md5.4 KiB
- resources/validation-testing.md14.5 KiB
- scripts/Invoke-DedicatedPoolTool.ps1Script941 B
- scripts/dedicated-pool-tool/DedicatedPoolMessageSanitizer.csScript2.1 KiB
- scripts/dedicated-pool-tool/DedicatedPoolTool.csproj346 B
- scripts/dedicated-pool-tool/Program.csScript31.4 KiB
- scripts/dedicated_pool_runtime.pyScript116.9 KiB
- scripts/validate_dedicated_pool_spark.pyScript24.8 KiB
resources/dedicated-pool-discovery.md
Dedicated Pool Discovery and Assessment
Purpose: Extract schema from Synapse Dedicated SQL Pool using DACPAC or catalog queries and classify objects by complexity (T1-T4) Tools: SqlPackage CLI, Python 3.10+, Azure CLI Output:
<pool>.dacpac, SQL scripts, inventory, complexity assessment, and SQL Pool to Lakehouse gap reports
This phase is notebook-free. Do not use a discovery notebook or require notebook artifacts from the source or target workspace.
Table of Contents
| Section | Description |
|---|---|
| § DACPAC Extraction | SqlPackage commands for schema export |
| § Script Extraction | Extract individual SQL files from DACPAC |
| § Schema Inventory | Parse DACPAC to list tables, views, procedures |
| § Complexity Classification | T1-T4 classification contract |
| § Assessment Report | Generate JSON report with conversion estimates |
| § Migration Gap Report | Required SQL Pool to Lakehouse compatibility findings |
DACPAC Extraction
Prerequisites
Install SqlPackage:
Windows: Download SqlPackage
Linux/Mac:
dotnet tool install -g microsoft.sqlpackage
Authentication:
# Azure AD auth (recommended)
az login
$token = az account get-access-token --resource https://database.windows.net --query accessToken -o tsvExtract Command
# Define connection parameters
$synapseServer = "your-workspace.sql.azuresynapse.net"
$dedicatedPool = "your-pool-name"
$outputPath = "./dacpac_output"
New-Item -ItemType Directory -Force -Path $outputPath
# Extract DACPAC (Azure AD auth)
sqlpackage /Action:Extract `
/SourceConnectionString:"Server=tcp:$synapseServer,1433;Database=$dedicatedPool;Encrypt=True" `
/AccessToken:$token `
/TargetFile:"$outputPath/$dedicatedPool.dacpac" `
/p:ExtractAllTableData=False `
/p:VerifyExtraction=True `
/p:ExtractReferencedServerScopedElements=False `
/DiagnosticsFile:"$outputPath/extract.log"
# Check exit code
if ($LASTEXITCODE -eq 0) {
Write-Host "✅ DACPAC extracted successfully" -ForegroundColor Green
$dacpacSize = (Get-Item "$outputPath/$dedicatedPool.dacpac").Length / 1MB
Write-Host " Size: $([math]::Round($dacpacSize, 2)) MB"
} else {
Write-Host "❌ Extraction failed. Check extract.log" -ForegroundColor Red
Get-Content "$outputPath/extract.log" | Select-Object -Last 20
exit 1
}Do not place SQL passwords in command arguments or generated migration artifacts. If Azure AD authentication is unavailable, stop and have the operator configure an approved secret-backed authentication flow outside this skill.
Troubleshooting DACPAC Extraction
| Error | Cause | Resolution |
|---|---|---|
| Connection timeout | Firewall blocks IP | Add client IP to Synapse firewall rules |
| Authentication failed | AAD token expired | Re-run az login |
| SqlPackage not found | Not in PATH | Use full path: C:\Program Files\Microsoft SQL Server\160\DAC\bin\SqlPackage.exe |
| Cannot connect to server | Pool is paused | Resume Dedicated Pool in Azure Portal |
| Insufficient permissions | Lacks metadata visibility | Grant database CONNECT and VIEW DEFINITION; add narrower catalog permissions only when a failed query proves they are needed |
| Stored procedure body extraction returns empty/placeholder | Manual XML parsing uses wrong property | Use DacFx GetScript() (recommended) or read Property[@Name='BodyScript'].InnerText from DACPAC model.xml. Do NOT use Annotation[@Type='SysCommentsObjectAnnotation']/Property[@Name='Expression'] (that path does not exist). Property HeaderContents contains only the signature, not the body. |
Script Extraction
Defects #13-17 fixes: Package and maintain a deterministic DacFx discovery/conversion executable that handles DacFx SDK resolution, ModelLoadOptions, non-scriptable child objects, and built-in object filtering automatically.
Read the DACPAC Model
sqlpackage /Action:Script produces a deployment script only when given a target and does not create one file per source object. Do not use it as the inventory source. Run the maintained ../scripts/Invoke-DedicatedPoolTool.ps1 entry point against a .dacpac or a ZIP containing one DACPAC. That entry point builds dedicated-pool-tool/DedicatedPoolTool.csproj; its Program.cs pins the DacFx dependency, loads the resolved DACPAC with explicit ModelLoadOptions { LoadAsScriptBackedModel = true }, and emits normalized source evidence plus schema-inventory.json. A ZIP containing only a SQL project is rejected by default because MSBuild can execute arbitrary targets. Prefer compiling it in an isolated trusted environment and then passing the DACPAC; use -AllowTrustedProjectBuild only after reviewing and explicitly trusting the project.
Defect #14 fix: The packaged tool uses a pinned NuGet Microsoft.SqlServer.DacFx dependency declared in DedicatedPoolTool.csproj. The wrapper script clears MSBuildSDKsPath during dotnet run to ensure consistent DacFx resolution without manual environment configuration.
Defect #15 fix: The tool explicitly uses ModelLoadOptions { LoadAsScriptBackedModel = true } to ensure compatibility with installed DacFx versions.
Defect #16 fix: Wrap GetScript() and child-object traversal in exception handlers. Catch DacModelException, InvalidOperationException, and NotSupportedException; preserve the typed object record and add a NonScriptableObject blind spot instead of aborting discovery or classifying a child as Unknown.
Defect #17 fix: Filter out built-in system objects during classification. Use DacQueryScopes.UserDefined and additional checks to exclude:
Built-in types (
sys.*,dbo.sysname)Built-in roles (
public,db_owner, etc.)System schemas (
sys,INFORMATION_SCHEMA)DacFx child objects (columns, constraints, indexes, parameters) which belong in
supportingObjects, notobjects
Only user-defined top-level objects contribute to migratable-object counts and Unknown classification totals.
Use TSqlModel.GetObjects(DacQueryScopes.UserDefined) and classify objects by their DacFx ObjectType. Keep top-level conversion objects in objects, schemas/security principals and policies in evidenceObjects, and columns, constraints, indexes, parameters, and other children in supportingObjects. Only objects contributes to migratable-object and Unknown classification totals. At minimum, include:
schemas, tables, columns, data types, defaults, identities, sequences, and partition specifications
primary, foreign, unique, and check constraints; indexes, columnstore indexes, statistics, and materialized views
views, procedures, scalar/table functions, triggers, synonyms, and external objects
users, roles, permissions, row-level security, masking, workload groups, and classifiers
all model relationships and referenced-object identifiers, not regex-only
FROMandJOINmatches
For each object, use DacFx properties and relationships as the authoritative metadata. Call GetScript() only for top-level conversion and evidence objects. Catch DacModelException, InvalidOperationException, and NotSupportedException; preserve the typed object record and add a NonScriptableObject blind spot instead of aborting discovery or classifying a child as Unknown.
Source-Contract Edge Validation (Defect #3 Fix)
For every procedure dependency on a table or view, emit a source-contract edge during discovery containing the referencing object stable ID, referenced object stable ID and type, every referenced column identifier, the referenced object's discovered ordered projection, and a resolution status. Match identifiers with the source model's collation semantics. Set the status to Resolved only when every referenced column exists in that projection; otherwise set MissingReferencedColumn and record the exact missing-column set.
Critical: Validate source-contract edges before conversion starts, not after generation. An unresolved object or column relationship is a discovery blind spot and must set the affected procedure to ManualReviewRequired status before any notebook generation begins. Never attempt conversion for procedures with unresolved column contracts. An unresolved object or column relationship is a discovery blind spot, not permission to infer a contract from generated SQL.
Example: When uspComplex_SalesExceptionScan references columns OrderDateKey, ProductKey, and TotalProductCost from vwComplex_UnifiedSales, but that view's discovered projection does not expose those three columns, the discovery phase must record a MissingReferencedColumn status with the exact missing set ["OrderDateKey", "ProductKey", "TotalProductCost"], set the procedure's conversion status to ManualReviewRequired with no generated notebook, and continue discovering and converting independently eligible procedures.
// Illustrative core of the DacFx extractor (RECOMMENDED APPROACH)
using Microsoft.SqlServer.Dac.Model;
var options = new ModelLoadOptions { LoadAsScriptBackedModel = true };
var dacpac = TSqlModel.LoadFromDacpac("pool.dacpac", options);
var objects = dacpac.GetObjects(DacQueryScopes.UserDefined);
foreach (var sourceObject in objects)
{
var objectType = sourceObject.ObjectType.Name;
var objectName = sourceObject.Name?.ToString() ?? "";
// The packaged tool calls GetScript only for top-level/evidence objects
// and records supported DacFx exceptions as discovery blind spots.
// Serialize DacFx properties, relationships, and source text into the
// canonical inventory record. Do not infer names or dependencies by regex.
}Alternative: Manual XML parsing (use only when DacFx tool is unavailable):
# Extract stored procedure body from DACPAC model.xml
# CRITICAL: Use Property[@Name='BodyScript'], NOT Annotation[@Name='Expression']
$xml = [xml](Get-Content "extracted/model.xml")
$procedures = $xml.DataSchemaModel.Model.Element | Where-Object { $_.Type -eq 'SqlProcedure' }
foreach ($proc in $procedures) {
$procName = $proc.Name
# CORRECT: Read from Property[@Name='BodyScript']
$bodyScriptProperty = $proc.Property | Where-Object { $_.Name -eq 'BodyScript' }
if ($bodyScriptProperty -and $bodyScriptProperty.InnerText) {
$sqlCode = $bodyScriptProperty.InnerText.Trim()
Write-Host "✓ Extracted $($sqlCode.Length) characters from $procName"
} else {
Write-Warning "⚠ Could not extract T-SQL body for $procName"
}
# INCORRECT patterns to avoid:
# ❌ $annotationElement.Property[@Name='Expression'] - this path does not exist
# ❌ $proc.Property[@Name='HeaderContents'] - contains only signature, not body
}Property location summary for manual XML parsing:
Full T-SQL body:
Element[@Type='SqlProcedure']/Property[@Name='BodyScript']/InnerTextSignature only:
Element[@Type='SqlProcedure']/Property[@Name='HeaderContents']/InnerText(e.g., "CREATE PROC [dbo].[uspName] AS")Name:
Element[@Type='SqlProcedure']/@Nameattribute
Do not attempt to read Annotation[@Type='SysCommentsObjectAnnotation']/Property[@Name='Expression'] — that XML path does not exist in DACPAC model.xml structure.
Supplement with Read-Only Catalog Queries
A DACPAC does not represent every operational or external dependency. Query source catalogs read-only and merge results into the same inventory. Record each query, timestamp, success/failure, and error text so missing permissions become visible assessment blind spots.
Required catalog coverage includes sys.schemas, sys.objects, sys.columns, sys.types, sys.default_constraints, sys.check_constraints, sys.key_constraints, sys.foreign_keys, sys.indexes, sys.index_columns, sys.partitions, sys.sql_modules, sys.sql_expression_dependencies, sys.database_principals, sys.database_permissions, sys.database_role_members, sys.security_policies, sys.masked_columns, sys.external_tables, sys.external_data_sources, sys.external_file_formats, sys.database_scoped_credentials, sys.pdw_table_distribution_properties, and available workload-management/catalog views. Use sys.sql_expression_dependencies.referenced_minor_id with sys.columns where available to corroborate column-level references; preserve a failed or incomplete resolution as a blind spot rather than falling back to regex-only parsing.
Never query table rows. Catalog and definition metadata only are permitted.
Schema Inventory
Canonical Inventory Contract
Write schema-inventory.json and schema-inventory.md from the merged DacFx and catalog results. The JSON root is an object with an objects array and a blindSpots array. Every object record must include the stable source identifier, schema, name, type, normalized sourceText and source path when applicable, DacFx properties, dependency identifiers, catalog evidence, and any discovery warnings. Preserve failed metadata queries in blindSpots.
Before classification, verify that every required gap category in dedicated-pool-gap-assessment.md has either collected evidence or an explicit query failure. Also verify every procedure-to-table/view source-contract edge. Any MissingReferencedColumn, unresolved referenced object, or unknown projection must be linked to the affected procedure and carried into the gap assessment before conversion. An empty pool is valid and must produce an empty inventory, zero counts, and no conversion work; it must not be padded with sample objects.
Output:
schema-inventory.json— structured data for downstream processingschema-inventory.md— human-readable summary
Complexity Classification
T1-T4 Classification Contract
Classify every source-bearing object from schema-inventory.json. Apply tiers from highest to lowest precedence; the first matching tier wins. Preserve every matched indicator as evidence rather than relying on an unexplained numeric score.
| Tier | Indicators | Conversion approach |
|---|---|---|
| T4 | Stored procedure; cursor or loop; temporary table; dynamic SQL; transaction; TRY/CATCH | Spark SQL notebook component planning; defer notebook cardinality and grouping until the post-discovery capacity and mapping assessment is approved |
| T3 | Window function; CTE; nested subquery; set operation; PIVOT/UNPIVOT | Individual conversion and focused semantic review |
| T2 | Join; CASE; GROUP BY; aggregate | Guided conversion with targeted tests |
| T1 | Simple projection/filter without a higher-tier indicator | Routine conversion and syntax validation |
Object size and a wide projection are supplemental effort indicators only; they must not lower a tier selected by a semantic indicator. Objects without source text remain in the inventory with classification Unknown and a reason that identifies the missing evidence.
Write both complexity-report.json and complexity-report.md. Each classified object must include its stable source identifier, schema, name, type, tier, matched indicators, line count, dependencies, and review status. The Markdown report must summarize tier counts and percentages, list all T4 and Unknown objects, and identify the conversion approach for each tier.
Assessment Report
Consolidated Discovery Report
Generate assessment-report.json from the canonical inventory and complexity report. Include:
generation timestamp and source pool identifier
total discovered objects and counts by type, schema, tier, and review status
all discovery blind spots and failed metadata queries
T4 and
Unknownobjects requiring manual reviewdependency blockers and recommended migration waves
discovered procedure count and the inventory inputs required to project target notebook and workspace item totals
effort assumptions and estimates, clearly labeled as planning estimates rather than commitments
If using the default planning heuristic, calculate estimated hours as $0.5T1 + 1T2 + 3T3 + 8T4$ and estimated days as hours divided by eight. Keep the coefficients in report metadata so reviewers can replace them. Never infer low effort for Unknown objects; report them separately until evidence is available.
Migration Gap Report
After inventory and complexity classification, execute the complete Dedicated Pool to Lakehouse Gap Assessment. Produce:
migration-gap-report.jsonmigration-gap-report.md
The report must assess every discovered object across every required gap category, identify metadata-query failures and unknowns, and list concrete evidence and disposition for each finding. It must also compare 1:1, N:1, and N:N procedure-notebook strategies using the discovered procedure inventory and projected workspace item demand. Present the Markdown report to the customer, then require the customer to provide and approve the complete mapping strategy and workspace placement before conversion. Complexity and effort reports do not satisfy this requirement.
Summary
This discovery phase provides:
DACPAC Extraction — Schema export from Synapse Dedicated Pool
Script Extraction — Individual SQL files for each object
Schema Inventory — Structured metadata (type, dependencies, line count)
Complexity Classification — T1-T4 tiers with conversion approach
Assessment Report — Effort estimate and recommendations
Migration Gap Report — Complete SQL Pool to Lakehouse compatibility findings and customer approval
Next Phase: Proceed to dedicated-pool-conversion.md only after the migration gap report is complete and approved.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills-for-fabric · skills/synapse-migration · commit f8fac11
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- microsoft/skills-for-fabric
AutoGineer is not affiliated with or endorsed by Microsoft or Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download synapse-migration.zip