我需要将写入时间戳作为许多表的表导出的一部分输出,尽管我无法找到一种不强制我显式选择语句中所有列的方法。
而不是这样做:
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
,address
和mobile
都有不同的写入时间。
从这两个示例中,您应该看到,并不总是存在一个适用于分区中所有列的写时间。
对于您的特定用例,您需要从DSBulk输出中找出在不同时间插入/更新分区片段的情况下使用哪个写时间。干杯!