【问题标题】:gocql SELECT * doesn't return all columnsgocql SELECT * 不返回所有列
【发布时间】:2015-03-17 23:56:03
【问题描述】:

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

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

然后我还想计算一些特定类型的消息,所以在我的 Go 应用程序中,我 ALTER 表以添加我以前没有的列。

我的应用程序正在增长,我开始有超过 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. 这是否来自我的请求,应该有所不同?
  2. 可能来自gocql驱动程序?
  3. 这种模式完全愚蠢吗?

我的临时解决方案是从system.schema_columns 表中选择列名并将所有这些都添加到我的 SELECT 查询中...

非常感谢您的帮助。

【问题讨论】:

    标签: go cassandra cql cassandra-2.0 gocql


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      感谢安迪的帮助。

      起初,我想考虑到你告诉我的,我宁愿有时在system.schema_columns 上做一个SELCT column_name,并在我改变我的表时刷新它。然后我会在strings.join() 我的SELECT FROM api_counters 中的列。它可以工作,但如果我有 2 个不同的实例,一个会更新架构,另一个会收到 GET 请求,那么这个实例仍然不知道新列。

      然后我重新安排了我的想法,发现显然还有另一种方法可以做到这一点,我只是针对这个架构进行了更改: CREATE TABLE stats_dev.api_counters ( date text, description text, all counter, PRIMARY KEY (date, description) ); 我正在根据我期望的描述更新该字段。到目前为止一切顺利。

      我知道这绝对是选项 3:我的模式不是最好的。

      【讨论】:

      • 这看起来是一种很棒的方法,也是一种更好的数据建模方法 :)
      猜你喜欢
      • 1970-01-01
      • 2014-09-02
      • 2015-08-29
      • 1970-01-01
      • 2013-11-04
      • 1970-01-01
      • 2012-10-07
      • 1970-01-01
      • 2014-01-03
      相关资源
      最近更新 更多