Cassandra select CQL:不能在通配符后添加列



我需要将写入时间戳作为许多表的表导出的一部分输出,尽管我无法找到一种不强制我显式选择语句中所有列的方法。

而不是这样做:

SELECT *, writetime(data) AS timestamp  FROM dls.licenses;

我必须这样做:

SELECT column1, column2, ... , writetime(data) AS timestamp  FROM dls.licenses;

这是非常不方便的,因为这意味着每当任何表的模式发生变化时,我都必须更改导出工具。

有更好的方法吗?

编辑:澄清一下,我得到的实际错误如下。语法在错误中呈现的方式可以认为SQL应该是正确的:

SELECT *, writetime(id) AS timestamp  FROM dls.licenses;
SyntaxException: line 1:8 mismatched input ',' expecting K_FROM (SELECT *[,]...)

编辑2:下面是用于此表的keyspace和create语句:

CREATE KEYSPACE IF NOT EXISTS dls WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': ‚1‘ };
CREATE TABLE IF NOT EXISTS dls.licenses (subscription_id text, id text, key text, data text, PRIMARY KEY (key));
CREATE INDEX IF NOT EXISTS ON dls.licenses (id);

BTW:我用的是最新的Cassandra 4.0.0 (GA)。

如果您要导出CSV或JSON文件,您可以考虑使用DataStax的dsbulk。

https://github.com/datastax/dsbulk

最新版本的dsbulk 1.8.0增加了导出writetime和ttl的支持。

https://docs.datastax.com/en/dsbulk/doc/dsbulk/reference/schemaOptions.html schemaOptions__schemaOptionsPreserveTimestamp

dsbulk unload -url myData.csv -k ks1 -t table1 --timestamp

WHERE子句指定必须查询哪些行。它由作为PRIMARY KEY一部分的列上的关系和/或在这些列上定义了二级索引组成。

  • 关系的列规范必须是下列之一:
  • 分区键的一个或多个成员
  • 集群列,仅当关系之前有其他关系指定分区键
  • 中的所有列时。
  • 使用CREATE INDEX建立索引的列。

在Cassandra 3.6及以后的版本中,添加ALLOW FILTERING只对非索引的集群列进行过滤。

您可以通过在需要写时间的列上创建二级索引来解决查询问题。请记住,二级索引会产生开销,并可能导致意想不到的后果。

SELECT *中的星号(*)是"ALL columns"的CQL语法因此,根据定义,不可能包含另一个列,因为即使对于本机CQL函数,也选择了所有列。因此,您需要枚举所有列名+列上的函数。

对Yuki的答案加1。我想补充的是,DSBulk为表中的每一列添加了一个WRITETIME()列,因为在读取整个分区之前,不可能提前知道分区中每一列的写时间。

请允许我用几个例子来解释。

<<h2>模式/h2>考虑这个表:

CREATE TABLE users_by_email (
email text,
name text,
address text,
mobile text,
PRIMARY KEY (email)
)
示例1

如果我们添加一条新记录,并为所有列指定一个值:

INSERT INTO users_by_email (email, name, address, mobile)
VALUES ('alice@staysafe.com', 'Alice', '221B Baker St', '098-765-432-109');

那么对于这个分区,所有的列都有相同的写时间。

示例2

考虑这样一种情况,一条记录在一段时间内被多个插入碎片化,例如:

INSERT INTO users_by_email (email, name)    VALUES ('dude@getvaccinated.now', 'Bob');
INSERT INTO users_by_email (email, address) VALUES ('dude@getvaccinated.now', '350 Fifth Ave');
INSERT INTO users_by_email (email, mobile)  VALUES ('dude@getvaccinated.now', '012-555-123-456');

每列name,addressmobile都有不同的写入时间。

从这两个示例中,您应该看到,并不总是存在一个适用于分区中所有列的写时间。

对于您的特定用例,您需要从DSBulk输出中找出在不同时间插入/更新分区片段的情况下使用哪个写时间。干杯!

最新更新