使用 cassandra inbuild `now()` 函数在 Python 驱动程序中生成带有模型的 TimeUUID

Use cassandra inbuild `now()` function to generate TimeUUID with Model in Python driver

我有代码

import time

from uuid import uuid4

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


class StudentModel(Model):
    __table_name__ = 'student'
    id = columns.UUID(primary_key=True, default=uuid4)
    created_timestamp = columns.TimeUUID(primary_key=True,
                                         clustering_order='DESC',
                                         default=cassandra.util.uuid_from_time(time.time()))
    name = columns.Text(required=True, default='')

class ClassRoomModel(Model):
    __table_name__ = 'class_room'
    id = columns.UUID(primary_key=True, default=uuid4)
    created_timestamp = columns.TimeUUID(primary_key=True,
                                         clustering_order='DESC',
                                         default=cassandra.util.uuid_from_time(time.time()))
    name = columns.Text(required=True, default='')

class StudentToClass(Model):
    __table_name__ = 'student_to_class_mapping'
    class_room_id = columns.UUID(primary_key=True)
    created_timestamp = \
        columns.TimeUUID(primary_key=True,
                         clustering_order='DESC',
                         default=cassandra.util.uuid_from_time(time.time()))
    student_id = columns.UUID()

class ClassToStudent(Model):
    __table_name__ = 'class_to_student_mapping'
    student_id = columns.UUID(primary_key=True)
    created_timestamp = \
        columns.TimeUUID(primary_key=True,
                         clustering_order='DESC',
                         default=cassandra.util.uuid_from_time(time.time()))
    class_room_id = columns.UUID()

if __name__ == '__main__':
    connection.setup(hosts=['localhost'],
                     default_keyspace='test')
    sync_table(StudentModel)
    sync_table(ClassRoomModel)
    sync_table(StudentToClass)
    sync_table(ClassToStudent)

    students = []
    for i in xrange(100):
        students.append(StudentModel.create(name='student' + str(i)))

    class_room = ClassRoomModel.create(name='class1')

    for student in students:
        print "Creating batch for: ", student.name
        with BatchQuery() as batch_query:
            ClassToStudent.batch(batch_query).create(
                student_id=student.id, class_room_id=class_room.id)
            StudentToClass.batch(batch_query).create(
                student_id=student.id, class_room_id=class_room.id)

这段代码工作正常,它也创建了记录。当我检查记录数时,它匹配 3 个表,但对于 test.student_to_class_mapping,它必须是 100,但它只给出 1.

cqlsh> select count(*) from test.student;

 count
-------
   100

(1 rows)
cqlsh> select count(*) from test.class_room ;

 count
-------
     1

(1 rows)
cqlsh> select count(*) from test.class_to_student_mapping;

 count
-------
   100

(1 rows)
cqlsh> select count(*) from test.student_to_class_mapping ;

 count
-------
     1

(1 rows)

我发现了问题,逻辑上是正确的,唯一的问题是 test.student_to_class_mapping 中的 clusturing_key

created_timestamp = \
    columns.TimeUUID(primary_key=True,
                     clustering_order='DESC',
                     default=cassandra.util.uuid_from_time(time.time()))

cassandra.util.uuid_from_time(time.time()) 无法为每条记录生成 Unique uuid。我可以使用 uuid1 但我已经遇到 .

的问题

我知道,我们可以使用now(),我把我的代码改成

from cassandra.query import BatchStatement, SimpleStatement
from cassandra.cqlengine import connection
...
...
    batch_query = BatchStatement()
    batch_query.add(
        SimpleStatement('INSERT INTO {0} '
            '("student_id", "created_timestamp", "class_room_id") '
            'VALUES ({1}, now(), {2})'.format(
                StudentToClass.column_family_name(),
                student.id, class_room.id)))
    batch_query.add(
        SimpleStatement('INSERT INTO {0} '
            '("student_id", "created_timestamp", "class_room_id") '
            'VALUES ({1}, now(), {2})'.format(
                ClassToStudent.column_family_name(),
                student.id, class_room.id)))   
    connection.session.execute(batch_query) 
...
... 

现在它工作正常并按照逻辑创建所有记录。

我想知道,有什么方法可以将now()与模型的create方法一起使用吗?

发生了什么:

default = None
    the default value, can be a value or a callable (no args)

(来自 https://datastax.github.io/python-driver/api/cassandra/cqlengine/columns.html

你的台词

default=cassandra.util.uuid_from_time(time.time())

在启动时进行评估并包含单个值作为 uuid。尝试这样的事情:

from uuid import uuid1,uuid4

class Comment(Model):
    photo_id = UUID(primary_key=True)
    comment_id = TimeUUID(primary_key=True, default=uuid1) # second primary key component is a clustering key
    comment = Text()

在这里找到。 https://datastax.github.io/python-driver/api/cassandra/cqlengine/query.html

另一(纯个人)评论 - 显式生成 uuid,因为之后经常需要它;)