【问题标题】:How to avoid escape character in Migrating the data from SQLDatabase to Cosmos DB如何避免将数据从 SQL 数据库迁移到 Cosmos DB 中的转义字符
【发布时间】:2018-07-12 13:48:39
【问题描述】:

我想将整个 SQL 数据库迁移到 Cosmos DB。在这个过程中 SQL 表列之一具有如下序列化数据

    [{"Id":"1","Type":"Phone","HeaderLabel":"HQ - Main Line","ContactNumber":"+9122222222"}]

序列化的数据代表一个类

  public class ContactNumber
{
    public string ContactNumberId { get; set; }
    public string Type { get; set; }
    public string HeaderLabel { get; set; }
    public string ContactNumber { get; set; }
}

在将数据保存在 sql 中时,我必须为类执行序列化和反序列化。

 public string _ContactNumbers { get; set; }

 public List<ContactNumber> ContactNumbers
    {
        get { return _ContactNumbers == null ? null : JsonConvert.DeserializeObject<List<ContactNumber>>(_ContactNumbers); }
        set { _ContactNumbers = value == null ? null : JsonConvert.SerializeObject(value); }
    }

使用迁移工具后,它会像这样更新

"ContactNumbers":"[{\"Id\":\"1\",\"Type\":\"Phone\",\"HeaderLabel\":\"HQ - Main Line\",\"ContactNumber\":\"+9122222222\"}]"

类保持不变。从 cosmos DB 获取数据时,我没有执行任何序列化和反序列化。

public List<ContactNumber> ContactNumbers 

在获取数据时会引发错误

Error converting value "[{"Id":"1","Type":"Phone","HeaderLabel":"HQ - Main Line","ContactNumber":"+9122222222"}]" to type 'System.Collections.Generic.List`1[CosmosDB.Models.ContactNumber]'. Path 'ContactNumber', line 1, position 2411.

错误是由于迁移后添加的字符串中的 Extra \ 字符造成的。

我不想对 cosmos DB 中的类进行序列化和反序列化,因为没有必要这样做。

那么在将数据从 SQL 数据库迁移到 Cosmos DB 文档时如何避免额外的 \?

【问题讨论】:

  • 请提供一些其他详细信息,例如指向您正在使用的特定工具的指针、如何调用它等。
  • 使用 Azure Cosmos DB 数据迁移工具docs.microsoft.com/en-us/azure/cosmos-db/import-data@BrendanGreen
  • 那么你用的是哪个API,你用的是GUI还是命令行版本?
  • GUI @BrendanGreen
  • 好吧,你真的没有付出太多的努力。我已经重读了您的问题,并且您有一个已序列化为字符串的类。那些前导斜杠是为了逃避引号字符。也就是说,生成的 JSON 有一个属性ContactNumbers,并包含一个字符串值,其中嵌入了需要转义的引号。话虽如此,您还没有说明为什么这是一个问题。

标签: azure azure-cosmosdb data-migration


【解决方案1】:

您可以使用Azure Function Cosmos DB Trigger 来处理创建的每个文档。请参考我的功能代码:

using System;
using System.Collections.Generic;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;

namespace ProcessJson
{
    public class Class1
    {
        [FunctionName("DocumentUpdates")]
        public static void Run(
        [CosmosDBTrigger(databaseName:"db",collectionName: "item", ConnectionStringSetting = "CosmosDBConnection",LeaseCollectionName = "leases",
            CreateLeaseCollectionIfNotExists = true)]
        IReadOnlyList<Document> documents,
        TraceWriter log)
        {
            log.Verbose("Start.........");
            String endpointUrl = "https://***.documents.azure.com:443/";
            String authorizationKey = "***";
            String databaseId = "db";
            String collectionId = "import";

            DocumentClient client = new DocumentClient(new Uri(endpointUrl), authorizationKey);

            for (int i = 0; i < documents.Count; i++)
            {
                Document doc = documents[i];
                if((doc.alreadyFormat == Undefined.Value) ||(!doc.alreadyFormat)){
                   String info = doc.GetPropertyValue<String>("info");
                   JArray o = JArray.Parse(info);

                   doc.SetPropertyValue("info", o);
                   doc.SetPropertyValue("alreadyFormat", true);
                   client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, doc.Id), doc); 

                   log.Verbose("Update document Id " + doc.Id);

                }

            }
        }
    }
}

另外请参考案例:Azure Cosmos DB SQL - how to unescape inner json property

希望对你有帮助。

【讨论】:

  • 它的作品。只有一个问题,触发器被触发 2 次。第一次插入文档时,第二次在 Azure 函数触发器中更新文档后。是否可以在我们插入文档时而不是在更新后触发一次触发器?
  • @SatyaraySingh 抱歉耽搁了,您可以尝试添加诸如“alreadyFormat”之类的属性并检查其值以控制更新操作。
猜你喜欢
  • 2018-09-02
  • 2018-12-14
  • 2021-01-03
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多