2017-06-19 3 views
0

Je code commeUtilisez la fonction `cassandra inbuild maintenant()` pour générer TimeUUID avec le modèle dans le pilote Python

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) 

Ce code fonctionne très bien, et il a créé des documents aussi. Quand je vérifie le nombre d'enregistrements, il correspond à 3 tables, mais pour test.student_to_class_mapping, il doit être 100, mais il ne donne que 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) 

Je trouve la question, correcte sage logique son, seul problème est clusturing_key dans test.student_to_class_mapping.

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()) n'est pas en mesure de générer Unique UUID pour chaque enregistrement. Je peux utiliser uuid1 mais je suis déjà confronté à un problème avec uuid1.

Je sais, nous pouvons utiliser now(), je change mon code pour

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) 
... 
... 

Maintenant, sa belle et la création de tous les documents de travail selon la logique.

Je veux savoir, est-il possible d'utiliser now() avec la méthode create du modèle?

Répondre

1

Qu'est-ce happend:

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

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

Votre ligne avec

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

mais j'ai évalué au moment du démarrage et contenait une seule valeur UUID. Essayez quelque chose comme ceci:

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

Trouvé ici. https://datastax.github.io/python-driver/api/cassandra/cqlengine/query.html

Une autre remarque (pur personnelle) - générer explicite UUID comme un besoin souvent par la suite;)

+0

Merci Jan, je l'ai déjà face à problème avec 'uuid1'. https://stackoverflow.com/questions/43807341/cassandra-timeuuid-flood-file-descriptor-when-use-uuid-in-default – Nilesh

+0

si vous pouvez me donner un exemple pour utiliser 'now()' qui sera très utile . – Nilesh

+0

Si vous utilisez uuid à partir de librairies standards pythons, il ne devrait y avoir aucun problème - le seul problème de gestion de fichier ouvert que je connaisse vient de libuuid (qui est plus rapide). – Mandraenke