2013-05-13 11 views
9

WICHTIG einzufügen Wenn Sie mit diesem Problem heute zu tun haben, verwenden Sie das neue cassandra-Treiber von DataStax (dh Import cassandra), da es die meisten dieser gemeinsamen Probleme und don löst Benutze den alten cql Treiber nicht mehr, er ist veraltet! Diese Frage ist alt, bevor der neue Treiber gerade in Entwicklung war, und wir mussten eine unvollständige alte Bibliothek namens cql verwenden (import cql < - verwende das nicht mehr, gehe zum neuen Treiber).Wie ein Datetime in eine Cassandra 1.2 Zeitstempel Spalte

Intro Ich benutze die Python-Bibliothek CQL, um auf eine Cassandra 1.2-Datenbank zuzugreifen. In der Datenbank habe ich eine Tabelle mit einer Timestamp-Spalte und in meinem Python-Code muss eine Datetime in die Spalte eingefügt werden. Beispiel wie folgt:

Tabelle

CREATE TABLE test (
    id text PRIMARY KEY, 
    last_sent timestamp 
); 

Der Code

import cql 
import datetime 
... 
cql_statement = "update test set last_sent = :last_sent where id =:id" 
rename_dict = {} 
rename_dict['id'] = 'someid' 
rename_dict['last_sent'] = datetime.datetime.now() 
cursor.execute (cql_statement, rename_dict) 

Das Problem

Wenn ich den Code der tatsächlichen cql Anweisung ausgeführt ausführen, wie dies :

update test set last_sent =2013-05-13 15:12:51 where id = 'someid' 

Dann schlägt es mit einem Fehler

Bad Request: line 1:XX missing EOF at '-05' 

Das Problem, dass die cql Bibliothek zu sein scheint, ist (‚‘) nicht entkommen oder die Datetime konvertieren, bevor die Abfrage ausgeführt wird.

Die Frage Was ist der richtige Weg, dies ohne manuell zu tun, das Datum zu entkommen und in der Lage sein, einen vollständigen Zeitstempel speichern mit mehr Präzision in eine cassandra Timestamp-Spalte?

Vielen Dank im Voraus!

Antwort

7

Hat abhi bereits erklärt dies mit den Millisekunden seit Epoche als Long-Wert von cqlsh getan werden kann, jetzt müssen wir es in machen arbeiten der Python-Code.

Wenn Sie die cql-Bibliothek verwenden, wird diese Konvertierung (von datetime in Millisekunden seit Epoche) nicht ausgeführt, damit das Update funktioniert und Sie immer noch die erforderliche Genauigkeit haben, um die datetime in Millisekunden seit Epoche zu konvertieren.

Quelle Mit dieser nützlichen Frage: Getting millis since epoch from datetime, insbesondere diese Funktionen (die kleine Änderung stelle ich gemacht):

Die Lösung

import datetime 

def unix_time(dt): 
    epoch = datetime.datetime.utcfromtimestamp(0) 
    delta = dt - epoch 
    return delta.total_seconds() 

def unix_time_millis(dt): 
    return long(unix_time(dt) * 1000.0) 

Für dieses Beispiel der Code wäre :

cql_statement = "update test set last_sent = :last_sent where id =:id" 
rename_dict = {} 
rename_dict['id'] = 'someid' 
rename_dict['last_sent'] = unix_time_millis(datetime.datetime.now()) 
cursor.execute (cql_statement, rename_dict) 

Sie können die Datetime in einen Long-Wert konvertieren, der die Anzahl der Millisekunden seit der Epoche enthält, und das ist alles, die Aktualisierung wird in eine äquivalente Form transformiert, die einen Long-Wert für den Timestamp verwendet.

Hoffe, dass es jemand anderes

10

Ich kann Ihnen sagen, wie es in Cqlsh zu tun. Versuchen Sie, diesen

update test set last_sent =1368438171000 where id = 'someid' 

Equivalent long-Wert für Datum Zeit 2013-05-13 15:12:51 ist 1368438171000

+1

Danke abhi, das ist genau das, was ich frage. Ich werde eine vollständige Antwort in einigen veröffentlichen. –

5

gut für mich hilft es funktioniert direkt mit

update test set last_sent = '2013-05-13 15:12:51' where id = 'someid' 

Keine Notwendigkeit, etwas zu konvertieren. So in Python Sie es mit dem Datetime-Wert als String tun können:

cursor.execute("UPDATE test SET ts=:ts WHERE id=:id;", 
    dict(ts=your_datetime.isoformat(), id=id)) 
+0

Das funktionierte nicht, als diese Frage gestellt wurde, und darum habe ich gefragt. Können Sie weitere Informationen zur Version der von Ihnen verwendeten cql-Bibliothek bereitstellen? –

+0

Cassandra 2 mit CQL3, tut mir leid, dass ich das nicht erwähnt habe, ich wollte diese Methode hier nur für andere posten. – webjunkie

+0

Es ist in Ordnung, das Problem ist, dass Ihre Antwort für eine andere Frage ist, das Update, das Sie auf dem ersten Codeblock geschrieben haben, soll auf Cqlsh verwendet werden und ist eine CQL (Cassandra Query Language) -Anweisung, die Frage ist, diese Abfrage auszuführen von Python mit der Python-CQL-Bibliothek (nicht die Cassandra-Abfragesprache). –

1

Die meisten Lösungen sind gültig, ich will nur ein einfacheres vorschlagen:

from datetime import datetime 

my_date = int(float(datetime.now().strftime("%s.%f"))) * 1000 

update test set last_sent = my_date where id = 'someid' 
+0

Jede Art der Konvertierung des Datums zu lang ist ja gültig, also sollte es auch funktionieren. Für den Leser nutzen Sie einfach den neuen Cassandra-Treiber von Datastax, da er die meisten dieser Probleme löst und den alten CQL-Treiber nicht mehr verwendet, er ist veraltet! –

1

Ich weiß es ist ein 2 Jahre alte Frage, aber wenn jemand auf der Suche nach einer Antwort ist, verwenden Sie eine datetime-Instanz anstelle des Zeitstempels. Python-Treiber sollten jedoch intelligent mit einem Integer/Float umgehen.

+0

Ja, zonked, die Frage ist von vor dem neuen Python-Treiber von Datastax sogar existierte (das erklärt den Import CQL im Code). Der Zeitstempel in der Frage bezieht sich jedoch auf den Zeitstempel des Cassandra-Typs, in Cassandra gibt es keinen Datetime-Typ. Und wie Sie sehen können, verwendet der Python-Code bereits datetime. Ihre Antwort sollte lauten "Verwenden Sie den neuen Treiber". Immer noch ein gültiger Punkt tho –

Verwandte Themen