ashmit-001
ashmit-001

Reputation: 402

Exception thrown: 'Microsoft.Azure.Cosmos.CosmosException', Bad Request while bulk importing JSON to Azure Cosmos DB

I'm trying to bulk import a JSON file containing list of JSONs to Azure Cosmos DB from .Net 4.6.1 console application.

I'm successfully able to create the database and the container. However I'm getting the following error at Line 40 and the items aren't getting created. Error :

DocDBTrace Error: 0 : Operation will NOT be retried. Current attempt 0, Status Code: BadRequest Exception thrown: 'Microsoft.Azure.Cosmos.CosmosException' in Microsoft.Azure.Cosmos.Client.dll Exception thrown: 'System.AggregateException' in mscorlib.dll

Sample Code :

class Program
{

private static string EndpointUrl = $"";
private const string AuthorizationKey = "";
private const string DatabaseName = "TestDB";
private const string ContainerName = "BulkImportTest";
public static async Task Main(string[] args)
{
    string json = File.ReadAllText(@"BulkImport.json");

    List<StudentInfo> lists = JsonConvert.DeserializeObject<List<StudentInfo>>(json);

    CosmosClientOptions options = new CosmosClientOptions() { ConnectionMode = ConnectionMode.Gateway, AllowBulkExecution = true };
    CosmosClient cosmosClient = new CosmosClient(EndpointUrl, AuthorizationKey, options);

    try
    {
        Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync(DatabaseName);
        Console.WriteLine(database.Id);
        Container container = await database.CreateContainerIfNotExistsAsync(ContainerName, "/SId");
        Console.WriteLine(container.Id);
        List<Task> tasks = new List<Task>();
        foreach (StudentInfo item in lists)
        {
                tasks.Add(container.CreateItemAsync(item, new PartitionKey(item.SId)));
        }
        await Task.WhenAll(tasks); // Line 40
        }

    catch(Exception ex)
    {
            Console.WriteLine("Exception = " + ex.Message);
    }


    Console.ReadLine();
}
    class StudentInfo
    {
        public string SId { get; set; }
        public string SName { get; set; }
    }}

BulkImport.json :

  [
  {
    "SId": "101",
    "SName": "ABC",
  },
  {
    "SId": "102",
    "SName": "XYZ",
  }
  ]

Please help me regarding this.

After making the suggested updates I'm still facing similar issue :

DocDBTrace Error: 0 : Operation will NOT be retried. Current attempt 0, Status Code: BadRequest Exception thrown: 'Microsoft.Azure.Cosmos.CosmosException' in Microsoft.Azure.Cosmos.Client.dll Exception thrown: 'Microsoft.Azure.Cosmos.CosmosException' in mscorlib.dll

Upvotes: 2

Views: 8533

Answers (2)

Jim Xu
Jim Xu

Reputation: 23111

According to my test, when we create a new document, we must provide "id" property. For more details, please refer to the document.

For example

My .json file

 [{
         "SId": "101",
         "SName": "ABC"
     }, {
         "SId": "102",
         "SName": "XYZ"
     }
 ]

My code

        async static Task Main(string[] args)
        {
            string json = File.ReadAllText(@"E:\test.json");
            List<StudentInfo> lists = JsonConvert.DeserializeObject<List<StudentInfo>>(json);            
            CosmosClientOptions options = new CosmosClientOptions() { AllowBulkExecution = true, ConnectionMode = ConnectionMode.Gateway };
            CosmosClient cosmosClient = new CosmosClient(EndpointUrl, AuthorizationKey, options);
            Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync(DatabaseName);
            Console.WriteLine(database.Id);
            Container container = await database.CreateContainerIfNotExistsAsync(ContainerName,"/SId");
            Console.WriteLine(container.Id);
            List<Task> tasks = new List<Task>();
            foreach (StudentInfo item in lists)
            {
                item.Id = Guid.NewGuid().ToString();// add the line in your code
                tasks.Add(container.CreateItemAsync(item, new PartitionKey(item.SId))
                    .ContinueWith((Task<ItemResponse<StudentInfo>> task) =>
                    {
                        Console.WriteLine("Status: " + task.Result.StatusCode + "    Resource: " + task.Result.Resource.SId);
                    }));
            }
            await Task.WhenAll(tasks);
            Console.ReadLine();
        }
        class StudentInfo
        {            
            public string SId { get; set; }
            public string SName { get; set; }
            [JsonProperty(PropertyName = "id")]// add the code in your custom object
            public string Id { get; set; }//add the code in your custom object

        }
    }

enter image description here

Upvotes: 4

Matias Quaranta
Matias Quaranta

Reputation: 15583

Your documents do not contain the partition key.

Either make the Partition Key Path in the container match to some of your attributes (for example /SID), or make sure your JSON data contains documents with the funcId attribute.

[
  {
    "SID": "101",
    "SName": "ABC",
    "funcId" : "Something"
  }
  {
    "SID": "102",
    "SName": "XYZ",,
    "funcId" : "Something"
  }
  ]

Then load your documents with:

foreach (StudentInfo item in lists)
{
        tasks.Add(container.CreateItemAsync(item, new PartitionKey(item.funcId)));
}

With a model:

class StudentInfo
{
    public string SId { get; set; }
    public string funcId { get; set; }
    public string SName { get; set; }
}

OR, drop the Container and create it like so:

Container container = await database.CreateContainerIfNotExistsAsync(ContainerName, "/SID");

Upvotes: 1

Related Questions