Compatibility and current limitations¶
This page describes the current repository code, not the full capabilities of Apache HBase. It deliberately separates API availability from verified behavior. No production guarantees or performance comparisons are implied by a passing smoke test.
Validation baseline¶
The project development image is Python 3.11; the bundled cluster is HBase 2.6.1 with simple authentication. Python 3.10+ syntax is used in runtime annotations. Other Python releases, HBase versions, secure clusters, and failure/recovery topologies need separate validation.
Known gaps and safe guidance¶
| Area | Current behavior | Guidance |
|---|---|---|
Scan.set_limit() |
Sets a Python attribute; the Table/ResultScanner path does not enforce a global row limit | Use scanner.next_batch(n) or itertools.islice, and close the scanner |
Scan.set_time_range() |
Time bounds are not included by Scan.to_protobuf() |
Do not use it as a time filter; use an application key design appropriate to the query |
Scan.add_column() |
Current protobuf construction raises TypeError for a non-empty bytes qualifier |
Use add_family() with a QualifierFilter or column-prefix filter when appropriate |
Get.set_time_range() / set_time_stamp() |
Finite upper bounds attempt unsupported protobuf message assignment; lower-bound handling is incomplete | Do not promise version/time filtering through these methods |
Get.set_filter() |
Stores the filter, but the current Get RPC path does not send it | Use a bounded Scan with a server-side filter |
| Multiple cell versions | Row flattens cells into one value per family/qualifier, losing versions and timestamps |
Do not use it to retrieve complete version history |
| BatchGet, BatchPut, Batch, BufferedMutator | Requests are ultimately sent one mutation/Get at a time | Convenience/buffering, not one RPC, bulk loading, or cross-row atomicity |
| Multi-column Increment result | Only one decoded counter is returned | Increment one counter per call if you need an unambiguous return value |
truncate_table(..., preserve_splits=True) |
The implementation deletes/recreates from column families; it does not preserve split keys | Treat it as destructive; do not promise retained splits, full table metadata, or previous disabled state |
table.invalidate_cache() |
Clears Table's cache, not every attached ClusterConnection scan cache | Recreate the Client/Table after truncate or major topology changes |
| Admin existence probes | table_exists() converts exceptions to False |
A false result may be a connectivity/permission failure; investigate before destructive actions |
| Resource cleanup and sharing | Cleanup methods exist, but not every low-level socket has a complete close path; caches can be shared across handles | Prefer bounded sessions; monitor resources; avoid untested concurrent/multi-table sharing |
| Security and failover | Custom znode paths, Kerberos/SASL/TLS, and Java-style retry/failover are not wired end-to-end | Do not describe this as a drop-in secure/HA Java Client replacement |
Scan boundaries and pagination¶
Both start and end rows default to inclusive in this driver. Set exclusivity explicitly with with_start_row(..., inclusive=False) or with_end_row(..., inclusive=False).
scan_page() returns the last emitted key whenever a page is nonempty, including a short final page. A resume key therefore does not prove that another row exists. Continue until an empty page; preserve the same filters, columns, and end boundary each time. Concurrent writes are not a snapshot, so resuming does not provide snapshot consistency.
Forward single-region recipes are tested separately from Region split/move behavior. Reverse scans and cross-region recovery require workload-specific verification; there is no claim of transparent recovery from every topology change.
Failure semantics¶
A timeout after Put, Delete, Increment, Append, or a conditional mutation can leave the outcome unknown. Replaying increments/appends may duplicate effects. Batches can be partly applied before an exception; no rollback is provided. BufferedMutator removes mutations from its buffer before sending, so a failed flush is not a retryable persistent queue.
Limit examples to disposable tables. Snapshot/restore and Region-management methods need explicit operational checks; a returned procedure ID is not confirmation of completion. Never exercise cluster-wide balancer changes as a routine documentation smoke test.
Maintenance policy¶
Correct documentation rather than silently promising unsupported semantics. Driver fixes should arrive with focused tests, followed by updates to this page and the affected recipes. The site build checks documentation links; local example verification is separate and is not exhaustive compatibility or security certification.