web-dev-qa-db-fra.com

Comment insérer une date/heure dans une colonne d'horodatage Cassandra 1.2

IMPORTANT Si vous rencontrez ce problème aujourd'hui, utilisez le nouveau pilote cassandra de datastax (c.-à-d. import cassandra), car il résout la plupart des problèmes courants et n'utilise pas l'ancien cql. conducteur plus, il est obsolète! Cette question est ancienne avant même que le nouveau pilote ne soit en développement et nous avons dû utiliser une ancienne bibliothèque incomplète appelée cql (import cql <- ne l'utilisez plus, passez au nouveau pilote).

Intro J'utilise la bibliothèque python cql pour accéder à une base de données Cassandra 1.2. Dans la base de données, j'ai une table avec une colonne timestamp et, dans mon code Python, une date/heure à insérer dans la colonne. Exemple comme suit:

Table

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

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

Le problème

Lorsque j'exécute le code, l'instruction cql exécutée est la suivante:

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

Puis il échoue avec une erreur

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

Le problème semble être que la bibliothèque cql n'échappe pas ('') ni ne convertit la date/heure avant d'exécuter la requête.

La question Quelle est la bonne façon de procéder sans quitter manuellement la date et pouvoir stocker un horodatage complet avec plus de précision dans une colonne d’horodatage de Cassandra?

Merci d'avance!

10

Est-ce que abhi a déjà indiqué que cela peut être fait en utilisant les millisecondes depuis Epoch comme une valeur longue de cqlsh, nous devons maintenant le faire fonctionner dans le code Python.

Lorsque vous utilisez la bibliothèque cql, cette conversion (de la date/heure en millisecondes depuis Epoch) n’a pas lieu afin de permettre à la mise à jour de fonctionner tout en conservant la précision nécessaire pour convertir la date/heure en millisecondes depuis Epoch.

Source En utilisant cette question utile: Obtenir des millis depuis Epoch depuis datetime , en particulier cela fonctionne (notez le petit changement que j'ai fait):

La solution

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)

Pour cet exemple, le code serait:

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)

Vous pouvez convertir la date/heure en une valeur longue contenant le nombre de millisecondes depuis Epoch et c'est tout, la mise à jour est transformée en une forme équivalente à l'aide d'une valeur longue pour l'horodatage.

J'espère que ça aide quelqu'un d'autre

7

Je peux vous dire comment le faire dans cqlsh. Essaye ça

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

La valeur longue équivalente pour date heure 2013-05-13 15:12:51 est 1368438171000

10
abhi

Eh bien pour moi cela fonctionne directement avec

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

Pas besoin de convertir quelque chose. Donc, en Python, vous pouvez le faire en utilisant la valeur datetime comme une chaîne:

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

Je sais que la question remonte à 2 ans, mais si quelqu'un cherche une réponse, utilisez une instance datetime plutôt que timestamp. Le pilote Python devrait gérer intelligemment un entier/float, cependant.

1
zonked.zonda

La plupart des solutions sont valables, je veux simplement en suggérer une plus simple:

from datetime import datetime

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

update test set last_sent = my_date where id = 'someid'
1
Patrick