scyllapy
scyllapy copied to clipboard
Problem accessing varint in scylla when value > 32767
I have a table where one of the primary key cols is a varint, with possible values up to 999999. At first I couldn't get scyllapy to work at all when trying to do a parameterized SELECT on this table, I kept getting back "[]" as the result.all(). It would work with a simple string non-parameterized query.
Eventually I tracked this down to some kind of problem with how scyllapy is handling ints. I found for values below 128 if I wrap the int in extra_types.TinyInt() then it works as a parameter. For values between 128 to 32767 I can use extra_types.SmallInt(). However when I try to use extra_types.BigInt() for values > 32767 it fails and I get back "[]" again as the result.
All attempts I made to pass a plain python int value as a parameter, whether directly in an execute() call, in a Query or PreparedQuery, etc. all seem to fail. They only work when I wrap them in one of the extra_types. How can I get this to work with values > 32767?
For anyone running into this, I found that using struct to pack the desired int into a 3-byte big-endian (despite my servers being little endian, I think this has something to do with "network packing"? or something about how Scylla deals with varints?) by using struct's 4-byte packing and then taking only the last 3 bytes, it works:
param_varint_greater_than_32767 = struct.pack('>i', 999999)[1:]
If there is some better way to do this that I missed, let me know.
Hello. I have tried using bigint on current version and it works on biggest possible bigint value.
import asyncio
from scyllapy import Scylla, extra_types as et
async def main() -> None:
"""None."""
scylla = Scylla(["localhost"])
await scylla.startup()
await scylla.execute(
"CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = "
"{'class': 'SimpleStrategy', 'replication_factor': 1};",
)
await scylla.use_keyspace("test")
await scylla.execute("DROP TABLE IF EXISTS test;")
await scylla.execute("CREATE TABLE IF NOT EXISTS test (id VARINT PRIMARY KEY);")
await scylla.execute(
"INSERT INTO test (id) VALUES (?);",
[et.BigInt(9223372036854775807)],
)
rows = await scylla.execute("SELECT * FROM test;")
for row in rows.all():
print(row)
if __name__ == "__main__":
asyncio.run(main())