使用 python cassandra 驱动程序创建新记录时如何设置服务器端时间戳

How to set serverside timestamp when create new record using python driver for cassandra

我有 cassandra 模型如下。

from uuid import uuid4
from uuid import uuid1

from cassandra.cqlengine import columns, connection
from cassandra.cqlengine.models import Model
from cassandra.cqlengine.management import sync_table


class BaseModel(Model):
    __abstract__ = True

    id = columns.UUID(primary_key=True, default=uuid4)
    created_timestamp = columns.TimeUUID(primary_key=True,
                                         clustering_order='DESC',
                                         default=uuid1)
    deleted = columns.Boolean(required=True, default=False)

class OtherModel(BaseModel):
    __table_name__ = 'other_table'
    name = columns.Text(required=True, default='')



if __name__ == '__main__':
    connection.setup(hosts=['localhost'],
                     default_keyspace='test')
    sync_table(OtherModel)

    OtherModel.create(id='d43ca2c3-b670-4efc-afd7-b46ada88c3fc', name='test')

当我创建记录时,它设置 created_timestamp 我的系统或从我执行此代码的位置。

我的系统和 cassandra 服务器有不同的时间戳。

如果我在系统时间为 2017-01-13 10:20:30 的地方执行此操作,那么它会将时间戳设置为相同。如果我再次从另一个系统执行相同的操作,其中 timestamp2017-01-13 10:20:20,那么它设置相同。

当我运行查询时

select * from test.other_table where id=d43ca2c3-b670-4efc-afd7-b46ada88c3fc limit 1;

应该return我latest(last)最后插入的记录,但由于系统时间戳与我插入记录的位置不同,它给出了第一个插入的第一个记录。

根据上述 python 代码创建的模式是:

CREATE TABLE test.other_table (
    id uuid,
    created_timestamp timeuuid,
    deleted boolean,
    name text,
    PRIMARY KEY (id, created_timestamp)
) WITH CLUSTERING ORDER BY (created_timestamp DESC)

鉴于您的示例,created_timestamp 是主键的组成部分,因此 table 中将有两个不同的行 10:20:30 和 10:20:20。将 order 设置为 DESC,您的读取查询将 return 值按排序顺序排列,最大的在前,或 2017-01-13 10:20:30。插入行的顺序无关紧要,因为 created_timestamp 是一个聚簇列。

如果 created_timestamp 不是主键的一部分,那么 Cassandra 只会 return 最新值。 Cassandra 有一个由协调器生成的内部单元格时间戳,用于确定何时插入或更新单元格。在读取请求期间,Cassandra 的合并进程使用它来确定最后插入的值。您不能从客户端代码中设置它,但您可以使用 CQL writetime() 函数查看更新插入时间。

例如,

select id, dateOf(created_timestamp), writetime(name) from other_table;

将return:

 id                                   | system.dateof(created_timestamp) | writetime(name)
--------------------------------------+----------------------------------+------------------
 d43ca2c3-b670-4efc-afd7-b46ada88c3fc |         2017-01-14 23:09:08+0000 | 1484435348108365
 d43ca2c3-b670-4efc-afd7-b46ada88c3fc |         2017-01-14 23:07:30+0000 | 1484435250481046

如果您希望使用协调器的时间戳,则必须使用 CQL 语句而不是 object-mapper:

import uuid
from cassandra.cluster import Cluster

cluster = Cluster()
session = cluster.connect("test")

stmt = session.prepare(
"""
    INSERT INTO test.other_table (id,created_timestamp) VALUES (?,now());
"""
)
session.execute(stmt,[uuid.uuid4()])