2013-05-13 8 views
9

WAŻNE Jeśli masz do czynienia z tym problemem dzisiaj korzystać z nowej Cassandra-sterownik z datastax (tj Cassandra import), ponieważ rozwiązuje większość tych wspólnych problemów i Don nie używa już starego sterownika cql, jest przestarzały! To pytanie jest stare, zanim nowy sterownik był jeszcze w fazie rozwoju i musieliśmy użyć niekompletnej starej biblioteki o nazwie cql (import cql < - nie korzystaj już z tego, przenieś się do nowego sterownika).Jak wkładać datetime do Cassandry 1,2 timestamp kolumna

Intro Używam biblioteki cql python, aby uzyskać dostęp do bazy danych Cassandra 1.2. W bazie danych mam tabelę z kolumną znacznika czasu iw moim kodzie Pythona mam datetime do wstawienia w kolumnie. Przykład następująco:

Tabela

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

Kod

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) 

Problem

Kiedy wykonać kod rzeczywisty oświadczenie CQI wykonywany jest tak :

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

Wtedy nie powiedzie się z powodu błędu

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

Problem wydaje się, że biblioteka CQI nie ucieka („”) lub konwersji datetime przed uruchomieniem kwerendy.

Pytanie Co to jest poprawny sposób to zrobić bez konieczności ręcznego ucieczce datę i być w stanie przechowywać pełną znacznik czasu z większą precyzją do kolumny Cassandra datownika?

Z góry dziękuję!

Odpowiedz

7

Has abhi już wspomniano, można to zrobić za pomocą milisekund od epoki jako długą wartość z cqlsh, teraz musimy zrobić to praca w kod Pythona.

Podczas korzystania z biblioteki cql ta konwersja (z datetime do milisekund od epoki) nie dzieje się tak, aby aktualizacja działała i nadal ma dokładność, jakiej potrzebujesz do konwersji datetime na milisekundy od epoki.

Źródło Stosując tę ​​użyteczną pytanie: Getting millis since epoch from datetime, W szczególności funkcje (zwróć uwagę na małą zmianę zrobiłem):

Rozwiązanie

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) 

W tym przykładzie kod byłby :

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) 

Można przekonwertować datetime na długą wartość zawierającą liczbę milisekund od epoki i to wszystko, aktualizacja jest przekształcana na równoważną formę przy użyciu długiej wartości znacznika czasu.

Nadzieja pomaga kogoś innego

10

Mogę ci powiedzieć, jak to zrobić w cqlsh. Spróbuj tego

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

Equivalent długą wartość dla daty czasu 2013-05-13 15:12:51 jest 1368438171000

+1

Dzięki Abhi, właśnie o to proszę. Będę zamieszczać pełną odpowiedź w kilku. –

5

No dla mnie to działa bezpośrednio z

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

ma potrzeby konwertowania coś. Więc w Pythonie można to zrobić przy użyciu wartości datetime jako wyrażenie:

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

To nie działało, kiedy to pytanie zostało opublikowane, i dlatego poprosiłem. Czy możesz podać więcej informacji na temat wersji używanej biblioteki cql? –

+0

Cassandra 2 z CQL3, przepraszam, że o tym nie wspomniałem, chciałem opublikować tę metodę tutaj dla innych. – webjunkie

+0

Jest ok, problem polega na tym, że twoja odpowiedź dotyczy innego pytania, aktualizacja, którą napisałeś na pierwszym bloku kodu, ma być używana na cqlsh i jest instrukcją CQL (Cassandra Query Language), pytanie dotyczy wykonania tego zapytania z Pythona przy użyciu biblioteki python cql (nie języka zapytań cassandra). –

1

Większość rozwiązań jest ważna, po prostu chcę się sugerować prostsze:

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

Każdy typ konwersji daty na długą jest prawidłowy, tak więc powinien również działać. Nadal ze względu na czytelników po prostu użyj nowego sterownika cassandra z datastax, ponieważ rozwiązuje większość tych typowych problemów i nie używa już starego sterownika cql, jest przestarzały! –

1

wiem, że jest to 2-letnie pytanie, ale jeśli ktoś szuka odpowiedzi, użyj instancji datetime zamiast używać timestamp. Sterownik Pythona powinien jednak inteligentnie obsługiwać liczbę całkowitą/zmiennoprzecinkową.

+0

Tak, zonked, pytanie pochodzi sprzed, zanim istniał nowy sterownik Pythona z datastax (to wyjaśnia import cql w kodzie). Mimo to znacznik czasu w pytaniu odnosi się do datownika typu Cassandra, nie ma typu daty w kassandrze. I jak widać kod Pythona już używa datetime. Więc twoja odpowiedź powinna brzmieć "użyj nowego sterownika". Wciąż ważny punkt –

Powiązane problemy