2017-06-19 3 views
0

I-Code haben alsVerwenden cassandra inbuild `now()` Funktion TimeUUID mit Modell in Python-Treiber zu erzeugen

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) 

Dieser Code funktioniert gut, und es erstellt auch Aufzeichnungen. Wenn ich die Anzahl der Datensätze überprüfe, passt es für 3 Tabellen, aber für test.student_to_class_mapping muss es 100 sein, aber es gibt nur 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) 

ich das Problem gefunden, Logik weise seine korrekte, ist nur Ausgabe clusturing_key in 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()) ist nicht Unique UUID für jeden Datensatz erzeugen können. Ich kann uuid1 verwenden, aber ich habe bereits ein Problem mit uuid1.

Ich weiß, wir now() verwenden können, ich den Code ändern zu

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

Nun ist es gut funktioniert und die Erstellung aller Datensätze per Logik.

Ich möchte wissen, gibt es eine Möglichkeit, now() mit Modell create Methode zu verwenden?

Antwort

1

Was passiert:

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

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

Ihre Linie mit

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

wurde beim Start ausgewertet und enthielt einen einzigen Wert als UUID. Probieren Sie etwas wie folgt aus:

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

hier gefunden. https://datastax.github.io/python-driver/api/cassandra/cqlengine/query.html

Weitere (rein persönliche) Bemerkung - erzeugen die UUID explizit als man braucht es oft danach;)

+0

Danke Jan, ich Gesicht Problem bereits mit 'uuid1'. https://stackoverflow.com/questions/43807341/cassandra-timeuuid-flood-file-descriptor-when-use-uuid-in-default – Nilesh

+0

Wenn Sie mir ein Beispiel geben können, '' now() 'zu verwenden, wird das sehr hilfreich sein . – Nilesh

+0

Wenn Sie Uuid von Pythons Standard-Bibliotheken verwenden, sollte es überhaupt kein Problem geben - das einzige offene Datei-Handle-Problem, das ich kenne, kommt von libuuid (was schneller ist). – Mandraenke

Verwandte Themen