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

时间:2017-01-13 18:06:28

标签: python cassandra cassandra-python-driver

我有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的情况下执行此操作,那么它将timestame设置为相同。如果我再次从另一个系统执行相同操作,timestamp2017-01-13 10:20:20,则设置相同。

当我运行像

这样的查询时
select * from test.other_table where id=d43ca2c3-b670-4efc-afd7-b46ada88c3fc limit 1;

它应该返回最后插入的latest(最后)记录,但是由于系统时间戳与我插入记录的位置不同,它会给出首先插入的第一条记录。

1 个答案:

答案 0 :(得分:1)

从上面的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是主键的组成部分,因此表中将有两个不同的行10:20:30和10:20:20。将订单设置为DESC时,您的读取查询将按排序顺序返回值,最大值为2017-01-13 10:20:30。插入行的顺序无关紧要,因为created_timestamp是一个聚类列。

如果created_timestamp不是主键的一部分,那么Cassandra将只返回最新值。 Cassandra具有由协调器生成的内部单元时间戳,该时间戳确定何时插入或更新单元。在读取请求期间,Cassandra的合并过程使用它来确定插入的最后一个值。您无法从客户端代码设置此项,但您可以使用CQL {{3}}函数查看upsert时间。

例如,

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

将返回:

 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()])