我的问题在下一期。
我的代码中有下一个简单的模型:
public class Client
{
public Guid Id { get; set; }
public string Name { get; set; }
}
我为它定义了一个Map:
public class CustomMappings : Mappings
{
public CustomMappings()
{
For<Client>().TableName("clients")
.PartitionKey(x => x.Id);
}
}
我通过 Table<TEntity>.CreateIfNotExist()
方法:
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; }
}
我需要修改这个表,因为我想给它添加姓氏列。当然,当我尝试插入一个值时,我有一个例外:
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)
但是阶级 Cassandra.Data.Linq.Table<TEntity>
既不包含也不包含 .AlterOrCreate()
也不是 .Alter()
方法。而且,我们没有 .GetAlter()
中的方法 Cassandra.Mapping.Statements.CqlGenerator
.
哪种方法更适合解决这个问题?我有两个假设(除了创建一个pull请求,其中包含在github上datastax csharp驱动程序存储库所需的方法:))。
通过.cql文件中的cql脚本更改表,该脚本将以c代码执行。
在模型每次更改后创建新表并将旧数据迁移到其中。
我是cassandra的新手,我怀疑库中不存在所需的方法是有充分理由的。可能是因为cassandra是分布式数据库,所以修改后的一致性有问题吗?
1条答案
按热度按时间sxissh061#
cassandra模式中的更改应该非常准确地完成——您对它的分布式本质是正确的,在进行更改时需要考虑到这一点。通常建议只通过一个节点进行更改,在执行任何ddl语句(create/drop/alter)之后,您需要检查模式是否一致(例如,通过方法)
CheckSchemaAgreementAsync
的Metadata
类),在模式一致之前不要执行下一条语句。谈到更改本身-我不确定c#driver是否能够自动为schema生成更改,但是您可以按照文档中所述的cql命令执行更改(请仔细阅读限制!)。模式中的变化可分为两组:
无需迁移数据即可应用于表
这将需要创建具有所需结构的新表,并迁移数据。
在第一组中,我们可以做以下工作(可能不是完整的列表):
向表中添加新的正则列
从表中删除正则列
重命名群集列
第二组包括其他所有内容:
更改主键-向主键添加列或从主键中删除列
重命名非群集列
更改列的类型(建议使用所需的类型创建全新的列,复制数据,然后删除原始列-不建议使用相同的名称和不同的类型,因为这可能会使数据无法访问)
数据迁移可以由不同的工具完成,它可能取决于特定的需求,比如类型更改等,但情况不同。