Я хранил некоторую валюту в Кассандре как десятичные типы, и я обнаружил, что они не выходят так точно, как введено.Обычно это нормально, но иногда мне нужна точность (2 десятичных знака).Я попытался добавить точный синтаксис ко всему моему коду (создать таблицу, выбрать, вставить), и все это не с синтаксическими ошибками.Мне кажется, что более эффективно выполнять округление при обращении к базе данных, а не в Pandas DataFrame, поэтому я проверяю, есть ли у кого-нибудь решение.Я пробую синтаксисы в cqlsh и Python.
cqlsh 5.0.1 |Кассандра 3.11.2 |CQL spec 3.4.4 |Собственный протокол v4
Попытка сделать это для столбца таблицы:
CREATE TABLE IF NOT EXISTS myTable (
myid text,
price decimal(14,2),
PRIMARY KEY(id)
);
cassandra.protocol.SyntaxException: <Error from server: code=2000 [Syntax error in CQL query] message="line XXXXX no viable alternative at input '(' (... [decimal](...):>
Я увидел комментарий, что Кассандра не допускает точности в определениях таблиц, так что хорошо, двигаясь дальше.
Попытка сделать это при SELECT:
SELECT myid, cast(price as Decimal(14,2)) FROM myTable;
Syntax Exception: mismatched input '(' expecting ')' (...myid, cast(price as Decimal[(]...)
Я пропущу вставку, потому что ошибки избыточны, а также значения в DataFrame имеют правильную точность при вводе.Хранение и выбор таблицы - это то место, где она становится неуклюжей.
Ошибка SELECT, потому что невозможно преобразовать десятичное число в десятичное: http://cassandra.apache.org/doc/latest/cql/functions.html
Если я не могу указать точность в таблицесемантику, и я не могу сохранить ее как десятичную и привести ее с правильной точностью, я полагаю, что я вынужден:
- сохранить в double и привести к выбору, ИЛИ
- программноокруглить мой DataFrame после его возвращения?
Редактировать:
Для полноты картины это одно решение, которое работает, хотя я бы предпочел наиболее эффективное решениеЯ думаю, что это будет округление на уровне выборки данных.В любом CQL нет модификаторов точности, использующих десятичный тип для столбца цены.Решение адаптировано из ( Десятичное округление классов в Pandas ), так как df.round () не работает с Десятичным Python.
<set pandas row factory>
df = dbConnection.execute('SELECT myid, price FROM myTable')._current_rows
df[['price']] = df[['price']].applymap(lambda x: x.quantize(decimal.Decimal('.01')))