通过 C# 改变 Cassandra table 的正确方法

A correct way to alter Cassandra table via C#

我的问题在下一个

我的代码中有下一个简单模型:

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

    public string Name { get; set; }
}

我为它定义了一个映射:

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

我通过 Table<TEntity>.CreateIfNotExist() 方法创建了 table:

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

然后我可以通过以下方式插入我的数据:

IMapper mapper = new Mapper(session);

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

await mapper.UpdateAsync(client);

在此之后,我通过添加新的 属性:

来更改我的模型
public class Client
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }
}

我需要更改此 table,因为我想向其中添加姓氏列。 当然,当我尝试插入一个值时,我有没有它的异常:

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)

但是 class Cassandra.Data.Linq.Table<TEntity> 既不包含也不包含 .AlterOrCreate() 也不包含 .Alter() 方法。此外,我们在 Cassandra.Mapping.Statements.CqlGenerator.

中没有 .GetAlter() 方法

哪种方式更适合解决这个问题?我有两个假设(除了在 github :) 上使用所需方法创建拉取请求到 datastax csharp 驱动程序存储库之外)。

  1. 通过 .cql 文件中的 cql 脚本更改 tables,该文件将在 c# 代码中执行。
  2. 在每次更改模型后创建一个新的 table 并将旧数据迁移到它。

我是 Cassandra 的新手,我有充分理由怀疑库中不存在所需的方法。也许吧,因为Cassandra是分布式数据库,改后一致性有问题吗?

Cassandra 模式的更改应该非常准确地完成 - 您对它的分布式特性的看法是正确的,并且在进行更改时需要考虑到这一点。通常建议仅通过一个节点进行更改,并且在执行任何 DDL 语句 (create/drop/alter) 后,您需要检查模式协议(例如,通过 method CheckSchemaAgreementAsync of Metadata class), 在模式一致之前不执行下一条语句。

谈论更改本身 - 我不确定 C# 驱动程序是否能够自动生成架构更改,但您可以将更改作为 CQL 命令执行,如 documentation 中所述(请仔细阅读关于限制!)。模式的变化可以分为两组:

  1. 无需迁移数据即可应用于 table
  2. 这将需要创建具有所需结构的新 table 并迁移数据。

在第一组中,我们可以执行以下操作(可能不是完整列表):

  • 向 table
  • 添加一个新的常规列
  • 从 table
  • 中删除常规列
  • 重命名集群列

第二组包括其他所有内容:

  • 更改主键 - 添加或删除列to/from它
  • 重命名非集群列
  • 更改列的类型(强烈建议创建具有所需类型的全新列,复制数据,然后删除原始列 - 不建议使用不同类型的相同名称,因为它可能会使您的数据无法访问)

数据迁移可以通过不同的工具来完成,这可能取决于具体要求,比如类型更改等。但这是另一回事。