Ruslan Pogodin
Ruslan Pogodin

Reputation: 23

A correct way to alter Cassandra table via C#

My issue is in the next.

I have the next simple model in my code:

public class Client
{
    public Guid Id { get; set; }

    public string Name { get; set; }
}

I defined a mapping for it:

public class CustomMappings : Mappings
{
    public CustomMappings()
    {
        For<Client>().TableName("clients")
                     .PartitionKey(x => x.Id);
    }
}

I created the table via Table<TEntity>.CreateIfNotExist() method:

var table = new Table<Client>(session);
table.CreateIfNotExists();

And I can insert my data by the next way:

IMapper mapper = new Mapper(session);

var client = new Client
{
    Id = Guid.NewGuid(),
    Name = "John Smith"
};

await mapper.UpdateAsync(client);

After this, I've changed my model by adding a new property:

public class Client
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }
}

I need to alter this table, because I want to add surname column to it. Of course, I have the exception without it when I try to insert a value:

Cassandra.InvalidQueryException: Undefined column name surname
   at Cassandra.Requests.PrepareHandler.Prepare(PrepareRequest request, IInternalSession session, Dictionary`2 triedHosts)
   at Cassandra.Requests.PrepareHandler.Prepare(IInternalSession session, Serializer serializer, PrepareRequest request)
   at Cassandra.Session.PrepareAsync(String query, IDictionary`2 customPayload)
   at Cassandra.Mapping.Statements.StatementFactory.GetStatementAsync(ISession session, Cql cql, Nullable`1 forceNoPrepare)
   at Cassandra.Mapping.Mapper.ExecuteAsync(Cql cql)

But class Cassandra.Data.Linq.Table<TEntity> does not contain neither nor .AlterOrCreate() nor .Alter() methods. Also, we don't have .GetAlter() method in Cassandra.Mapping.Statements.CqlGenerator.

Which way is more appropriate to solve this problem? I have two assumptions (besides creating a pull request with needed methods to datastax csharp driver repository on github :)).

  1. To alter tables via cql script in .cql file which will be executed in c# code.
  2. To create a new table after each changes of a model and migrate old data to it.

I'm a newbee in Cassandra and I have suspicions that needed method does not exist in the library for good reason. Maybe, are there any problems with consistency after altering because Cassandra is distributed database?

Upvotes: 2

Views: 1375

Answers (1)

Alex Ott
Alex Ott

Reputation: 87244

Changes in the Cassandra's schema should be done very accurately - you're correct about distributed nature of it, and when making changes you need to take into account. Usually it's recommended to make changes via only one node, and after execution of any DDL statement (create/drop/alter) you need to check for schema agreement (for example, via method CheckSchemaAgreementAsync of Metadata class), and don't execute next statement until schema is in agreement.

Talking about changes themselves - I'm not sure that C# driver is able to automatically generate the changes for schema, but you can execute the changes as CQL commands, as described in documentation (please read carefully about limitations!). The changes in schema could be separated into 2 groups:

  1. That could be applied to table without need to migrate the data
  2. That will require creation of new table with desired structure, and migration of data.

In the first group we can do following (maybe not a full list):

  • Add a new regular column to table
  • Drop a regular column from table
  • Rename the clustering column

Second group includes everything else:

  • Changing the primary key - adding or removing columns to/from it
  • Renaming of non-clustering columns
  • Changing the type of the column (it's really recommended to create completely new column with required type, copy data, and then drop original column - it's not recommended to use the same name with different type, as it could make your data inaccessible)

Data migration could be done by different tools, and it may depend on the specific requirements, like, type change, etc. But it's a different story.

Upvotes: 2

Related Questions