2016-05-06 31 views
0

我正在构建一个简单的Scala Play应用程序,该应用程序使用Scala的Phantom DSL驱动程序将数据存储在Cassandra DB中。 Cassandra的一个很好的功能是可以进行部分更新,即只要您提供了关键列,您就不必为表中的所有其他列提供值。 Cassandra会根据密钥将数据合并到您现有的记录中。Cassandra和Phantom DSL部分插入

不幸的是,这似乎不适用于Phantom DSL。我有一个包含多列的表,我希望能够进行更新,只为键和其中一个数据列指定值,然后让Cassandra像往常一样将它合并到记录中,同时将所有其他数据列该记录保持不变。

但是,如果您没有在插入/更新语句中指定值,Phantom DSL将用空覆盖现有的列。

有没有人知道这方面的解决方法?我不想每次都读/写所有的数据列,因为最终数据列会很大。

仅供参考我使用同样的方法我的幻影编码在这些例子中:

https://github.com/thiagoandrade6/cassandra-phantom/blob/master/src/main/scala/com/cassandra/phantom/modeling/model/GenericSongsModel.scala

回答

2

这将是非常高兴看到一些代码,但部分更新是可能的幻象。幻影是一个不可改变的构建器,默认情况下它不会覆盖任何空值。如果你没有指定一个值,它将不会做任何事情。

database.table.update.where(_.id eqs id).update(_.bla setTo "newValue") 

将产生一个查询,其中只有您明确设置为something的值将被设置为null。请提供一些代码示例,您的问题看起来很奇怪,因为查询不跟踪表列以自动添加缺少的内容。

更新

如果你想删除列的值,例如,将其设置为null里面卡桑德拉基本上,幻影提供了不同的语法,做同样的事情:

database.table.delete(_.col1, _.col2).where(_.id eqs id)` 

此外,还甚至可以用同样的方式删除地图条目:

database.table.delete(_.props("test"), _.props("test2").where(_.id eqs id) 

这个假设propsMapColumn[Table, Record, String, _],因为props.apply(key: T)是类型安全的,因此它将遵循您为map列定义的键类型。

+0

谢谢,弗拉维安。我的代码现在处于流动状态,并且比上面链接的示例应用程序稍微复杂一点,所以我不能轻易将其放入此文章中。但是,我现在想知道是否可以通过在我的Scala/Phantom代码中将列声明为选项来解决问题,因为可能我的Scala数据类是问题。如果这不起作用,我会尝试更新方法。谢谢你的帮助。 –

+0

杜。我认为问题在于我正在使用插入来执行更新。在Cassandra中,这很好,因为Cassandra无论如何都将它视为一个upsert,对于我不需要关心记录是否已经存在或不需要关注的用例,这是很好的,因为我只写了关键字和一个或两个特定字段:默认的Cassandra行为就是我想要的。但它看起来像Phantom希望你明确地进行更新或插入,取决于密钥是否已经存在。我会尝试使用更新,就像Flavian建议的那样,看看会发生什么。 –

+0

更新(_。bla setTo“newvalue”)不再适用于幻像1.27.0。它看起来只有修改(_。bla setTo“newvalue”)可用。但是,它不会更新具有空值的列,这是此处的问题。 – yang