Complete runnable example / 完整示例¶
Documentation home · 中文手册 · More recipes
This page is the maintained standalone example for the documentation-only release. Copy the Python block below into a local file named docs_quickstart.py. It does not require changes to the driver source. Do not substitute the repository's legacy root-level example script, which is not updated by this documentation release.
Before running¶
- Install
hbase-driverwithpython -m pip install hbase-driver; venv is optional. - Use a development cluster with simple authentication and the default
/hbaseznode. - Ensure ZooKeeper and the advertised Master/RegionServer names are reachable.
- The script creates a unique
default:docs_demo_*table with thecffamily. It removes only that table after successful creation, even when a later operation fails. - If creation times out, inspect the printed name before deciding whether to clean up: the server may have created the table despite the error.
- Run without Python
-O, because this verification uses assertions.
中文:把下面代码保存为 docs_quickstart.py,在测试集群运行。代码会创建唯一临时表,完成验证后清理;不会删除预先存在的业务表。只导入文件不会连接集群。
Run locally or in the project container¶
For a cluster reachable from your Python environment:
On Windows PowerShell:
If you use this repository's Docker environment, save the file in the checkout (keep this local scratch file untracked), then run:
The dev service is this project's hbase_dev; HBASE_ZK is already set to hbase-zk:2181. Do not use another project's container. Stopping preserves the data volume.
Copyable script¶
"""Run a small, disposable HBase demonstration.
Use HBASE_ZK to select the cluster. Importing this module does not connect or
modify data. Running it creates a unique default:docs_demo_* table, then removes
only that table after successful creation. Use a development cluster.
"""
from __future__ import annotations
import os
from uuid import uuid4
from hbasedriver.client.buffered_mutator import BufferedMutator, BufferedMutatorParams
from hbasedriver.client.client import Client
from hbasedriver.common.table_name import TableName
from hbasedriver.filter import (
BinaryComparator,
CompareOperator,
FilterList,
PrefixFilter,
SingleColumnValueFilter,
)
from hbasedriver.hbase_constants import HConstants
from hbasedriver.operations.batch import BatchGet, BatchPut
from hbasedriver.operations.column_family_builder import ColumnFamilyDescriptorBuilder
from hbasedriver.operations.delete import Delete
from hbasedriver.operations.get import Get
from hbasedriver.operations.increment import CheckAndPut, Increment
from hbasedriver.operations.put import Put
from hbasedriver.operations.scan import Scan
def run_demo(zk_quorum: str) -> bytes:
"""Verify core operations and return the name of the cleaned-up table.
Exceptions propagate, including cleanup errors. If create_table times out,
inspect the printed name: the server may have created it despite the error.
"""
if not __debug__:
raise RuntimeError("Run this verification example without Python -O.")
name = TableName.value_of(
b"default", f"docs_demo_{uuid4().hex}".encode("ascii")
)
print(f"Using disposable table {name}", flush=True)
created = False
with Client({HConstants.ZOOKEEPER_QUORUM: zk_quorum}) as client:
with client.get_admin() as admin:
try:
admin.create_table(
name, [ColumnFamilyDescriptorBuilder(b"cf").build()]
)
created = True
descriptor = admin.describe_table(name)
assert len(descriptor.table_schema) == 1
schema = descriptor.table_schema[0]
assert [family.name for family in schema.column_families] == [b"cf"]
with client.get_table(name.ns, name.tb) as table:
table.put(
Put(b"user:001")
.add_column(b"cf", b"name", "张三".encode("utf-8"))
.add_column(b"cf", b"state", b"active")
)
row = table.get(Get(b"user:001"))
assert row is not None
assert row.get(b"cf", b"name").decode("utf-8") == "张三"
filters = FilterList(
operator=FilterList.Operator.MUST_PASS_ALL,
filters=[
PrefixFilter(b"user:"),
SingleColumnValueFilter(
b"cf", b"state", CompareOperator.EQUAL,
BinaryComparator(b"active"),
filter_if_missing=True,
latest_version_only=True,
),
],
)
scan = (
Scan(start_row=b"user:")
.with_end_row(b"user;", inclusive=False)
.add_family(b"cf")
.set_filter(filters)
)
with table.scan(scan) as scanner:
rows = scanner.next_batch(10)
assert [item.rowkey for item in rows] == [b"user:001"]
writes = BatchPut()
writes.add_put(Put(b"batch:1").add_column(b"cf", b"value", b"A"))
writes.add_put(Put(b"batch:2").add_column(b"cf", b"value", b"B"))
write_results = table.batch_put(writes)
assert write_results == [True, True]
reads = BatchGet([b"batch:1", b"batch:2"])
reads.add_column(b"cf", b"value")
results = table.batch_get(reads)
assert results[b"batch:1"].get(b"cf", b"value") == b"A"
assert results[b"batch:2"].get(b"cf", b"value") == b"B"
count = table.increment(
Increment(b"counter:1").add_column(b"cf", b"count", 1)
)
assert count == 1
claim = CheckAndPut(b"job:1")
claim.set_check(b"cf", b"state", None)
claim.set_put(Put(b"job:1").add_column(b"cf", b"state", b"claimed"))
first_claim = table.check_and_put(claim)
second_claim = table.check_and_put(claim)
assert first_claim is True
assert second_claim is False
params = BufferedMutatorParams()
params.write_buffer_periodic_flush = 0
with BufferedMutator(table, params) as mutator:
mutator.mutate(
Put(b"buffer:1").add_column(b"cf", b"value", b"saved")
)
mutator.flush()
buffered = table.get(Get(b"buffer:1"))
assert buffered is not None
assert buffered.get(b"cf", b"value") == b"saved"
table.delete(Delete(b"batch:1"))
assert table.get(Get(b"batch:1")) is None
finally:
if created:
admin.disable_table(name)
admin.delete_table(name)
print(f"Core examples passed; removed {name}", flush=True)
return name.tb
if __name__ == "__main__":
run_demo(os.getenv("HBASE_ZK", "127.0.0.1:2181"))
The last line starts with Core examples passed; removed default:docs_demo_, followed by the unique table name. This verifies basic schema inspection, CRUD, filtering, batch result shapes, counters, conditional writes, and buffered writes. JSON, pagination, Append, and RowMutations have separate recipes.
A passing example is not a production compatibility guarantee. See current limitations before relying on time ranges, multiple versions, concurrency, secure authentication, or Region failover.