gocql SELECT * 不返回所有列

标签 go cassandra cql cassandra-2.0 gocql

我在尝试为我的应用程序实现一些计数器时遇到了这种奇怪的行为。 基本上,我做了一个像这样的柜台:

CREATE TABLE stats_dev.log_counters (
  date text PRIMARY KEY,
  all counter
);

然后我也想计算一些特定类型的消息,因此在我的 Go 应用程序中,我更改了表格以添加以前没有的列。

我的应用程序正在不断增长,我开始拥有超过 30 列(不应超过 50 列),当我想要检索所有这些计数器时,结果中缺少一些列。

query := s.Query(`SELECT * FROM `+_apiCountersTable+` WHERE date IN ?`, dates)
res, err := query.Iter().SliceMap()

这会返回 34 列中的 30 列。虽然,当我在 CQLSH 上执行请求时:

cqlsh:stats_dev> SELECT * FROM api_counters WHERE date = 'total';

我得到了正确的完整结果。所以:

  1. 这是否来 self 的要求,应该有所不同?
  2. 这可能来自 gocql司机?
  3. 这种模式完全愚蠢吗?

我的临时解决方案是从 system.schema_columns 表中 SELECT 列名称,并将所有这些添加到 strings.Join() 到我的 SELECT 查询中...

非常感谢您的帮助。

最佳答案

我不熟悉 gocql 库,但听起来您可能会遇到不重新准备语句和 CASSANDRA-7910 的组合。 .

每当一个请求准备好时(比如 Select * from ___ where date in 中正在做什么?),它会向 cassandra 发送一个请求,cassandra 会使用该表的列元数据进行响应,因此当您收到对从 cassandra 查询回来,您知道可以查找哪些列。看起来 gocql 有一个名为“自动查询准备”的功能,它可能会将您的请求视为准备好的语句。

当您更改表时,准备好的语句不会在客户端更新,因此解决此问题的唯一方法是重新准备语句(不确定您是否具有 gocql 的控制级别)。然而,这仍然不起作用,因为 cassandra ( CASSANDRA-7910 ) 中存在一个错误,它不会返回新列,因为它本身会在其一侧缓存准备好的语句,并且在架构更改时不会使其无效。此问题已在 2.1.3 中修复(即将推出),可能值得在 git 中的 cassandra-2.1 分支上尝试此操作,看看是否可以解决您的问题。

在应用程序运行时更改架构并不是一种异常模式,因此这种情况应该可行,但不幸的是不行。我会研究是否有一种方法可以在 gocql 中重新准备语句。

我看到 cluster.go 中有一个 stmtsLRU var。如果你能以某种方式做到这一点,你就可以使准备好的语句无效。如果没有办法做到这一点,最好针对 gocql 提出问题,因为您可以在其他驱动程序中再次重新准备语句。我知道java驱动程序允许你这样做,但会给你一个警告。我想这可能是 gocql 和其他驱动程序之间的一个很大的区别,因为在其他驱动程序中,您显式使用准备好的语句对象,而在 gocql 中,它会在库中自动为您处理。

由于 cassandra bug 很突出,我认为您应该坚持不使用准备好的语句,而是进行如下查询:SELECT * FROM api_counters WHERE date = 'total';

关于gocql SELECT * 不返回所有列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28033756/

相关文章:

cassandra - 如何在聊天应用程序中按最后回复时间排序房间实体?

go - 构建 llgo+llvm 失败

mongodb - Non-relational db,哪个才是正确的选择

gocql 无法将 blob 解码为 *[20]uint8

java - 尝试将 csv 文件中的一些值插入到 cassandra

cassandra - 在Cassandra中进行选择,其中id!= null

Cassandra 时间序列排序

api - 无法使用golang docker sdk从docker容器获取日志

Paypal OAuth : 400 Error even after specifying Host

go - func 的语法 Golang 错误