cassandra十进制精度问题

vltsax25  于 2021-06-14  发布在  Cassandra
关注(0)|答案(1)|浏览(322)

我在cassandra中存储了一些十进制类型的货币,我发现它们的输出并不像输入的那样精确。这通常是正常的,但有时我需要精度(2位小数)。我尝试向我的所有代码(create table、select、insert)添加精确语法,但都失败了,出现语法错误。我觉得在数据库调用上舍入比在pandasDataframe中舍入更有效,所以我想看看是否有人有解决方案。我正在尝试cqlsh和python中的语法。
cqlsh 5.0.1 | cassandra 3.11.2 | cql规范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](...):>

我看到一条评论说cassandra不允许表定义精确,很好,继续。
尝试在select上执行此操作:

SELECT myid, cast(price as Decimal(14,2)) FROM myTable;

Syntax Exception: mismatched input '(' expecting ')' (...myid, cast(price as Decimal[(]...)

我将跳过插入,因为错误是多余的,而且Dataframe中的值在输入时具有正确的精度。table的存储和选择是它变得不稳定的地方。
选择失败,因为无法将十进制转换为十进制:http://cassandra.apache.org/doc/latest/cql/functions.html
如果我不能在表语义中指定精度,也不能将其存储为十进制并以适当的精度强制转换,我想我必须:
储存在双重和铸造选择,或
在返回Dataframe后以编程方式对其进行舍入?
编辑:
为了完整性,这是一个可行的解决方案,尽管我更喜欢最有效的解决方案,我认为应该在数据获取级别进行舍入。任何cql中都没有精度修饰符,对price列使用decimal类型。由于df.round()不适用于python decimal,因此解决方案改编自(Pandas中的decimal类舍入)。

<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')))
nxowjjhe

nxowjjhe1#

与sql数据库相比,cql不允许自定义十进制精度等,所以您只需要使用 decimal . 你收到的数据 cqlsh 格式由 cqlsh 本身-在默认配置中它只调用 str 关于python的 Decimal 键入(请参见代码)。如果十进制分隔符设置为不同于的值,它可能会调用另一个格式化程序 . ,或者如果设置了千位分隔符。
但我建议不要依赖 cqlsh 实现,直接使用驱动程序,并格式化接收 decimal 你想怎样就怎样。

相关问题