Python bindings for ScyllaDB/Cassandra using scylla-rust-driver
Project description
rsylla
High-performance Python bindings for ScyllaDB/Cassandra using the official scylla-rust-driver.
Features
- High Performance: Built on top of the official Rust driver for ScyllaDB
- Full API Coverage: Every function/method from the Rust driver has a Python equivalent
- Type Hints: Complete type annotations for better IDE support
- Async Runtime: Efficient async operations handled by Tokio runtime
- Easy to Use: Pythonic API that feels natural
Installation
pip install rsylla
Building from source
You'll need Rust and maturin installed:
# Install maturin
pip install maturin
# Build and install
maturin develop --release
Quick Start
from rsylla import Session
# Connect to ScyllaDB cluster
session = Session.connect(["127.0.0.1:9042"])
# Execute a query
result = session.execute(
"SELECT * FROM system.local WHERE key = ?",
{"key": "local"}
)
# Iterate over rows
for row in result:
print(row.columns())
Usage Examples
Creating a Session
from rsylla import SessionBuilder
# Using SessionBuilder for advanced configuration
session = (
SessionBuilder()
.known_nodes(["127.0.0.1:9042", "127.0.0.2:9042"])
.user("username", "password")
.use_keyspace("my_keyspace", case_sensitive=False)
.connection_timeout(5000) # 5 seconds
.pool_size(10)
.compression("lz4")
.tcp_nodelay(True)
.build()
)
Executing Queries
# Simple query
result = session.execute("SELECT * FROM users")
# Query with parameters
result = session.execute(
"SELECT * FROM users WHERE id = ?",
{"id": 123}
)
# Get first row
row = result.first_row()
if row:
print(row.columns())
# Get single row (raises exception if not exactly one row)
row = result.single_row()
# Iterate over all rows
for row in result:
print(row[0], row[1], row[2])
Using Query Objects
from rsylla import Query
# Create a query with configuration
query = (
Query("SELECT * FROM users WHERE id = ?")
.with_consistency("QUORUM")
.with_page_size(1000)
.with_timeout(10000)
.with_tracing(True)
)
result = session.query(query, {"id": 123})
# Check tracing info
if result.tracing_id():
print(f"Trace ID: {result.tracing_id()}")
Prepared Statements
# Prepare a statement
prepared = session.prepare("INSERT INTO users (id, name, email) VALUES (?, ?, ?)")
# Execute prepared statement
result = session.execute_prepared(
prepared,
{"id": 1, "name": "John Doe", "email": "john@example.com"}
)
# Prepared statements with configuration
prepared = (
prepared
.with_consistency("LOCAL_QUORUM")
.with_serial_consistency("SERIAL")
)
result = session.execute_prepared(prepared, {"id": 2, "name": "Jane", "email": "jane@example.com"})
Batch Operations
from rsylla import Batch
# Create a batch
batch = Batch("logged") # or "unlogged" or "counter"
# Add statements to batch
batch.append_statement("INSERT INTO users (id, name) VALUES (?, ?)")
batch.append_statement("INSERT INTO users (id, name) VALUES (?, ?)")
# Configure batch
batch = (
batch
.with_consistency("QUORUM")
.with_timestamp(1234567890)
)
# Execute batch with values for each statement
result = session.batch(
batch,
[
{"id": 1, "name": "User 1"},
{"id": 2, "name": "User 2"}
]
)
Working with Results
result = session.execute("SELECT * FROM users")
# Get all rows
rows = result.rows()
print(f"Found {len(rows)} rows")
# Get rows as dictionaries
rows_dict = result.rows_typed()
for row_dict in rows_dict:
print(row_dict)
# Get column specifications
col_specs = result.col_specs()
for spec in col_specs:
print(f"Column: {spec['name']}, Type: {spec['typ']}")
# Check for warnings
if result.warnings():
print("Warnings:", result.warnings())
# Boolean check
if result:
print("Query returned rows")
Keyspace Operations
# Change keyspace
session.use_keyspace("another_keyspace", case_sensitive=False)
# Get current keyspace
current_ks = session.get_keyspace()
print(f"Current keyspace: {current_ks}")
# Wait for schema agreement
agreed = session.await_schema_agreement()
print(f"Schema agreement reached: {agreed}")
Error Handling
from rsylla import ScyllaError
try:
result = session.execute("INVALID QUERY")
except ScyllaError as e:
print(f"Query error: {e}")
Consistency Levels
The following consistency levels are supported:
ANYONETWOTHREEQUORUMALLLOCAL_QUORUM(orLOCALQUORUM)EACH_QUORUM(orEACHQUORUM)LOCAL_ONE(orLOCALONE)
Serial consistency levels:
SERIALLOCAL_SERIAL(orLOCALSERIAL)
Batch Types
logged- Default, atomicity guaranteedunlogged- No atomicity guarantee, better performancecounter- For counter updates
Compression Types
lz4- LZ4 compressionsnappy- Snappy compressionNone- No compression
Type Mapping
Python types are automatically converted to CQL types:
| Python Type | CQL Type |
|---|---|
bool |
boolean |
int |
int, bigint |
float |
float, double |
str |
text, varchar |
bytes |
blob |
list |
list |
dict |
map |
None |
NULL |
API Reference
SessionBuilder
known_node(hostname: str)- Add a known nodeknown_nodes(hostnames: List[str])- Add multiple known nodesuse_keyspace(keyspace_name: str, case_sensitive: bool)- Set default keyspaceconnection_timeout(duration_ms: int)- Set connection timeoutpool_size(size: int)- Set connection pool sizeuser(username: str, password: str)- Set authentication credentialscompression(compression: Optional[str])- Set compression typetcp_nodelay(nodelay: bool)- Enable/disable TCP_NODELAYtcp_keepalive(keepalive_ms: Optional[int])- Set TCP keepalivebuild()- Build the session
Session
connect(nodes: List[str])- Create a session (static method)execute(query: str, values: Optional[Dict[str, Any]])- Execute a queryquery(query: Query, values: Optional[Dict[str, Any]])- Execute a Query objectprepare(query: str)- Prepare a statementexecute_prepared(prepared: PreparedStatement, values: Optional[Dict[str, Any]])- Execute prepared statementbatch(batch: Batch, values: List[Dict[str, Any]])- Execute a batchuse_keyspace(keyspace_name: str, case_sensitive: bool)- Change keyspaceawait_schema_agreement()- Wait for schema agreementget_cluster_data()- Get cluster metadataget_keyspace()- Get current keyspace
Query
__init__(query: str)- Create a querywith_consistency(consistency: str)- Set consistency levelwith_serial_consistency(serial_consistency: str)- Set serial consistencywith_page_size(page_size: int)- Set page sizewith_timestamp(timestamp: int)- Set timestampwith_timeout(timeout_ms: int)- Set timeoutwith_tracing(tracing: bool)- Enable/disable tracingis_idempotent()- Check if idempotentset_idempotent(idempotent: bool)- Set idempotencyget_contents()- Get query string
PreparedStatement
Similar methods to Query, plus:
get_id()- Get prepared statement IDget_statement()- Get query string
QueryResult
rows()- Get all rowsfirst_row()- Get first row or Nonesingle_row()- Get single row (raises exception if not exactly one)first_row_typed()- Get first row as dictionaryrows_typed()- Get all rows as dictionariescol_specs()- Get column specificationstracing_id()- Get tracing IDwarnings()- Get query warnings- Supports iteration,
len(), and boolean checks
Row
columns()- Get all column valuesas_dict()- Convert to dictionaryget(index: int)- Get column by index- Supports indexing with
[]andlen()
Batch
__init__(batch_type: str)- Create a batchappend_statement(query: str)- Add a statementappend_query(query: Query)- Add a Query objectappend_prepared(prepared: PreparedStatement)- Add a prepared statementwith_consistency(consistency: str)- Set consistency levelwith_serial_consistency(serial_consistency: str)- Set serial consistencywith_timestamp(timestamp: int)- Set timestampwith_timeout(timeout_ms: int)- Set timeoutwith_tracing(tracing: bool)- Enable/disable tracingis_idempotent()- Check if idempotentset_idempotent(idempotent: bool)- Set idempotencystatements_count()- Get number of statements
License
This project is dual-licensed under MIT or Apache-2.0, matching the scylla-rust-driver license.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rsylla-0.1.0-cp311-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: rsylla-0.1.0-cp311-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.11+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a299c11dc4c876f72aea94753986f7eed733f30b7b1c3d666207e21c636ada1
|
|
| MD5 |
9bafa970cb03500ac3d3e40af4f9f934
|
|
| BLAKE2b-256 |
4e9ccbdd59c8cbce4d5048a96576cb8d823d12700784ee47ed1677eff4d9e52d
|