I am trying to use the Cosmos DB .NET client to write some code that would clear existing Cosmos database and create a new structure. I want to delete a database with the specified name so that all its collections are gone and then create a new one. However I don't see a way to cleanly check if the database exists. There is the CreateIfNotExists method but this is not what I want. I want to remove the existing database. The only way I can think of is to catch the CosmosException and check for 404 status code but it seems like there should be some API to check for existence or some result object.
How to check if database exists in Cosmos DB?
Asked Answered
I believe the official SDK method to determine if a database exists is CreateDatabaseIfNotExistsAsync
on CosmosClient, which according to docs will return a 200 StatusCode
if exists. Once you have that result, you can delete it from the reference, as shown in this example.
// An object containing relevant information about the response
DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync(databaseId, 10000);
// A client side reference object that allows additional operations like ReadAsync
Database database = databaseResponse;
...
// Delete the database from Azure Cosmos.
await database.DeleteAsync();
You can query Cosmos DB to see if a database exists without having to do a Get in a try block. Here is the code to do it.
QueryDefinition query = new QueryDefinition(
"select * from c where c.id = @databaseId")
.WithParameter("@databaseId", "database1");
FeedIterator<dynamic> resultSet = client.GetDatabaseQueryIterator<dynamic>(query);
List<dynamic> databases = new List<dynamic>();
while (resultSet.HasMoreResults)
{
FeedResponse<dynamic> response = await resultSet.ReadNextAsync();
}
You will want to do something as shown below
var cosmosClient = new CosmosClient("yourConnectinString");
var database = cosmosClient.GetDatabase("dbname");
// Will either return 200 if exist
// Will return 404 is not exists
try
{
var response = await database.ReadAsync();
}
catch (CosmosException ex)
{
if (ex.StatusCode.Equals(HttpStatusCode.NotFound))
{
// Does not exist
}
}
As suggested by Microsoft's documentation
I Created a method to check if the database exists.
/// <summary>
/// Checks if a database exists.
/// </summary>
/// <param name="databaseName">Name of the database to check.</param>
/// <returns>True, if the database exists, otherwise false.</returns>
public async Task<bool> DatabaseExistsAsync(string databaseName)
{
var databaseNames = new List<string>();
using (FeedIterator<DatabaseProperties> iterator = cosmosClient.GetDatabaseQueryIterator<DatabaseProperties>())
{
while (iterator.HasMoreResults)
{
foreach (DatabaseProperties databaseProperties in await iterator.ReadNextAsync())
{
databaseNames.Add(databaseProperties.Id);
}
}
}
return databaseNames.Contains(databaseName);
}
/// <summary>
/// Checks if a container exists.
/// </summary>
/// <param name="containerName">Name of the container to check.</param>
/// <returns>True, if the container exists, otherwise false.</returns>
public async Task<bool> ContainerExistsAsync(string databaseName, string containerName)
{
var databaseExists = await this.DatabaseExistsAsync(databaseName);
if (!databaseExists)
{
return false;
}
var containerNames = new List<string>();
var database = this.cosmosClient.GetDatabase(databaseName);
using (FeedIterator<ContainerProperties> iterator = database.GetContainerQueryIterator<ContainerProperties>())
{
while (iterator.HasMoreResults)
{
foreach (ContainerProperties containerProperties in await iterator.ReadNextAsync())
{
containerNames.Add(containerProperties.Id);
}
}
}
return containerNames.Contains(containerName);
}
A more realized version of the solution given above:
async Task<bool> DoesDatabaseExist(CosmosClient client, string databaseId)
{
QueryDefinition query = new QueryDefinition(
"select * from c where c.id = @databaseId")
.WithParameter("@databaseId", databaseId);
FeedIterator<dynamic> resultSet = client.GetDatabaseQueryIterator<dynamic>(query);
while (resultSet.HasMoreResults)
{
FeedResponse<dynamic> response = await resultSet.ReadNextAsync();
if (response.Count > 0) return true;
}
return false;
}
If you're using @azure/cosmos
npm package, after looking at the source it seems like the right way to do this is:
async function databaseExists(dbid: string): Promise<boolean> {
try {
await getClient().database(dbid).read();
} catch (err: any) {
if (err.code === StatusCodes.NotFound) {
return false;
}
}
return true;
}
© 2022 - 2024 — McMap. All rights reserved.
client.ReadDatabaseAsync(...)
, and if it throwsDocumentClientException
with 404, then it doesn't exist. I would just create an extension that wrapsReadDatabaseAsync
. – Stefaniastefanie