Migration Guide
This guide explains how to migrate your data from Azure Digital Twins to Konnektr Graph, or between different Konnektr Graph deployments.
Migration Scenarios
From Azure Digital Twins to Konnektr Graph
Migrate from Azure Digital Twins to either hosted or self-hosted Konnektr Graph.
Between Konnektr Graph Deployments
Move data between hosted and self-hosted Konnektr Graph instances.
From Other Digital Twin Platforms
Migrate from other DTDL-compatible platforms.
1. Choose Your Target Deployment
Option A: Hosted Konnektr Graph (Recommended)
- Create account at ktrlplane.konnektr.io
- Deploy a new Konnektr Graph resource
- Get your endpoint:
https://your-graph-name.api.graph.konnektr.io
- Set up Auth0 authentication
Option B: Self-Hosted Konnektr Graph
- Deploy using Self-Hosted Guide
- Configure authentication (JWT, API keys, or development mode)
- Get your endpoint URL
2. Migration Approaches
A. Using Azure Digital Twins SDKs (Recommended)
The Azure Digital Twins SDK approach works for all scenarios and provides the easiest migration path:
Benefits:
- ✅ Works with both hosted and self-hosted Konnektr Graph
- ✅ Handles all DTDL model complexities
- ✅ Built-in retry logic and error handling
- ✅ Same code works for Azure → Konnektr migration
Setup:
- Source (Azure Digital Twins): Use
DefaultAzureCredential
- Target (Hosted Konnektr Graph): Use custom Auth0
TokenCredential
- Target (Self-Hosted): Use custom JWT or API key
TokenCredential
Note: See Using Azure Digital Twins SDKs for complete authentication setup.
Example Migration Scripts
# Example migration script for Python
# This script copies models, twins, and relationships from Azure Digital Twins to AgeDigitalTwins
from azure.identity import DefaultAzureCredential
from azure.digitaltwins.core import DigitalTwinsClient
import requests
import json
# Azure Digital Twins configuration
adt_url = "https://your-adt-instance.api.eus.digitaltwins.azure.net"
adt_client = DigitalTwinsClient(adt_url, DefaultAzureCredential())
# AgeDigitalTwins configuration
age_base_url = "https://your-age-instance.com/api"
age_headers = {"Authorization": "Bearer your-token"}
# Copy models
def copy_models():
models = adt_client.list_models()
for model in models:
response = requests.post(f"{age_base_url}/models",
json=model.serialize(),
headers=age_headers)
print(f"Copied model: {model.id}")
# Copy twins
def copy_twins():
query = "SELECT * FROM digitaltwins"
twins = adt_client.query_twins(query)
for twin in twins:
response = requests.put(f"{age_base_url}/digitaltwins/{twin['$dtId']}",
json=twin,
headers=age_headers)
print(f"Copied twin: {twin['$dtId']}")
if __name__ == "__main__":
copy_models()
copy_twins()
How to Run:
- Install
azure-identity
andazure-digitaltwins-core
via pip - Run with
python copy_adt.py
// Example migration script for C#
using Azure.Core;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using System.Text.Json;
public class AdtMigration
{
private readonly DigitalTwinsClient adtClient;
private readonly HttpClient ageClient;
public AdtMigration()
{
var credential = new DefaultAzureCredential();
adtClient = new DigitalTwinsClient(
new Uri("https://your-adt-instance.api.eus.digitaltwins.azure.net"),
credential);
ageClient = new HttpClient();
ageClient.BaseAddress = new Uri("https://your-age-instance.com/api/");
ageClient.DefaultRequestHeaders.Add("Authorization", "Bearer your-token");
}
public async Task CopyModelsAsync()
{
await foreach (var model in adtClient.GetModelsAsync())
{
var json = JsonSerializer.Serialize(model);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
await ageClient.PostAsync("models", content);
Console.WriteLine($"Copied model: {model.Id}");
}
}
public async Task CopyTwinsAsync()
{
var query = "SELECT * FROM digitaltwins";
await foreach (var twin in adtClient.QueryAsync<object>(query))
{
var json = JsonSerializer.Serialize(twin);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
await ageClient.PutAsync($"digitaltwins/{((dynamic)twin).Id}", content);
Console.WriteLine($"Copied twin: {((dynamic)twin).Id}");
}
}
}
How to Run:
- Use .NET 6+, add
Azure.DigitalTwins.Core
andAzure.Identity
NuGet packages - Run with
dotnet run
// Example migration script for JavaScript
const { DigitalTwinsClient } = require('@azure/digital-twins-core');
const { DefaultAzureCredential } = require('@azure/identity');
const axios = require('axios');
// Azure Digital Twins configuration
const adtUrl = 'https://your-adt-instance.api.eus.digitaltwins.azure.net';
const credential = new DefaultAzureCredential();
const adtClient = new DigitalTwinsClient(adtUrl, credential);
// AgeDigitalTwins configuration
const ageBaseUrl = 'https://your-age-instance.com/api';
const ageHeaders = { 'Authorization': 'Bearer your-token' };
async function copyModels() {
const models = adtClient.listModels();
for await (const model of models) {
await axios.post(`${ageBaseUrl}/models`, model, { headers: ageHeaders });
console.log(`Copied model: ${model.id}`);
}
}
async function copyTwins() {
const query = 'SELECT * FROM digitaltwins';
const twins = adtClient.queryTwins(query);
for await (const twin of twins) {
await axios.put(`${ageBaseUrl}/digitaltwins/${twin.$dtId}`, twin,
{ headers: ageHeaders });
console.log(`Copied twin: ${twin.$dtId}`);
}
}
async function main() {
await copyModels();
await copyTwins();
}
main().catch(console.error);
How to Run:
- Install
@azure/identity
and@azure/digital-twins-core
via npm - Run with
node copy_adt.js
B. Exporting to JSON-LD and Importing using the Import Jobs API
For large migrations or when using the import API, you can export your data to a JSON-LD file and upload it to blob storage for import.
Example Export Script (Python)
# Example script to export Azure Digital Twins data to JSON-LD format
from azure.identity import DefaultAzureCredential
from azure.digitaltwins.core import DigitalTwinsClient
import json
# Azure Digital Twins configuration
adt_url = "https://your-adt-instance.api.eus.digitaltwins.azure.net"
adt_client = DigitalTwinsClient(adt_url, DefaultAzureCredential())
def export_to_jsonld():
export_data = {
"@context": "https://www.w3.org/ns/activitystreams",
"@type": "Collection",
"models": [],
"twins": [],
"relationships": []
}
# Export models
models = adt_client.list_models()
for model in models:
export_data["models"].append(model.serialize())
# Export twins
query = "SELECT * FROM digitaltwins"
twins = adt_client.query_twins(query)
for twin in twins:
export_data["twins"].append(twin)
# Export relationships
rel_query = "SELECT * FROM relationships"
relationships = adt_client.query_twins(rel_query)
for rel in relationships:
export_data["relationships"].append(rel)
# Save to file
with open('export.jsonld', 'w') as f:
json.dump(export_data, f, indent=2)
print("Export completed: export.jsonld")
if __name__ == "__main__":
export_to_jsonld()
Steps
- Run the export script to generate
export.jsonld
. - Upload the file to your blob storage account.
- Use the AgeDigitalTwins import API to import the data (see API Reference).
For more details on the import API and supported formats, see the Reference documentation.