通过 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 驱动程序存储库之外)。
- 通过 .cql 文件中的 cql 脚本更改 tables,该文件将在 c# 代码中执行。
- 在每次更改模型后创建一个新的 table 并将旧数据迁移到它。
我是 Cassandra 的新手,我有充分理由怀疑库中不存在所需的方法。也许吧,因为Cassandra是分布式数据库,改后一致性有问题吗?
Cassandra 模式的更改应该非常准确地完成 - 您对它的分布式特性的看法是正确的,并且在进行更改时需要考虑到这一点。通常建议仅通过一个节点进行更改,并且在执行任何 DDL 语句 (create/drop/alter) 后,您需要检查模式协议(例如,通过 method CheckSchemaAgreementAsync
of Metadata
class), 在模式一致之前不执行下一条语句。
谈论更改本身 - 我不确定 C# 驱动程序是否能够自动生成架构更改,但您可以将更改作为 CQL 命令执行,如 documentation 中所述(请仔细阅读关于限制!)。模式的变化可以分为两组:
- 无需迁移数据即可应用于 table
- 这将需要创建具有所需结构的新 table 并迁移数据。
在第一组中,我们可以执行以下操作(可能不是完整列表):
- 向 table
添加一个新的常规列
- 从 table
中删除常规列
- 重命名集群列
第二组包括其他所有内容:
- 更改主键 - 添加或删除列to/from它
- 重命名非集群列
- 更改列的类型(强烈建议创建具有所需类型的全新列,复制数据,然后删除原始列 - 不建议使用不同类型的相同名称,因为它可能会使您的数据无法访问)
数据迁移可以通过不同的工具来完成,这可能取决于具体要求,比如类型更改等。但这是另一回事。
我的问题在下一个
我的代码中有下一个简单模型:
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 驱动程序存储库之外)。
- 通过 .cql 文件中的 cql 脚本更改 tables,该文件将在 c# 代码中执行。
- 在每次更改模型后创建一个新的 table 并将旧数据迁移到它。
我是 Cassandra 的新手,我有充分理由怀疑库中不存在所需的方法。也许吧,因为Cassandra是分布式数据库,改后一致性有问题吗?
Cassandra 模式的更改应该非常准确地完成 - 您对它的分布式特性的看法是正确的,并且在进行更改时需要考虑到这一点。通常建议仅通过一个节点进行更改,并且在执行任何 DDL 语句 (create/drop/alter) 后,您需要检查模式协议(例如,通过 method CheckSchemaAgreementAsync
of Metadata
class), 在模式一致之前不执行下一条语句。
谈论更改本身 - 我不确定 C# 驱动程序是否能够自动生成架构更改,但您可以将更改作为 CQL 命令执行,如 documentation 中所述(请仔细阅读关于限制!)。模式的变化可以分为两组:
- 无需迁移数据即可应用于 table
- 这将需要创建具有所需结构的新 table 并迁移数据。
在第一组中,我们可以执行以下操作(可能不是完整列表):
- 向 table 添加一个新的常规列
- 从 table 中删除常规列
- 重命名集群列
第二组包括其他所有内容:
- 更改主键 - 添加或删除列to/from它
- 重命名非集群列
- 更改列的类型(强烈建议创建具有所需类型的全新列,复制数据,然后删除原始列 - 不建议使用不同类型的相同名称,因为它可能会使您的数据无法访问)
数据迁移可以通过不同的工具来完成,这可能取决于具体要求,比如类型更改等。但这是另一回事。