Skip to main content
Version: Next

Data Management With ReductStore

ReductStore provides a set of methods to manage data in the database. This guide provides an overview of typical data management operations in ReductStore and explains how to perform them using the ReductStore SDKs or the HTTP API.

Changing Labels​

ReductStore doesn't allow you to change the contents of records, but it does allow you to change the labels of existing records. You can add, remove or update labels for a single record or for a batch of records to avoid HTTP requests overhead.

note

You should send a label as an empty string to remove it.

import time
import asyncio
from reduct import Client, Bucket, Batch


async def main():
# Create a client instance, then get or create a bucket
async with Client("http://127.0.0.1:8383", api_token="my-token") as client:
bucket: Bucket = await client.create_bucket("my-bucket", exist_ok=True)

# Send some records to the "py-example" entry with labels
ts = time.time()
await bucket.write(
"py-example",
b"Some binary data",
ts,
labels={"key1": "value1", "key2": "value2"},
)
await bucket.write(
"py-example",
b"Some binary data",
ts + 1,
labels={"key1": "value1", "key2": "value2"},
)

# Update labels of a record: remove "key2" and update "key1"
await bucket.update("py-example", ts, labels={"key1": "new-value", "key2": ""})
async with bucket.read("py-example", ts) as record:
assert record.labels["key1"] == "new-value"
assert "key2" not in record.labels

# Update labels in a batch
batch = Batch()
batch.add(ts, labels={"key1": "new-value", "key2": ""})
batch.add(ts + 1, labels={"key3": "value3"})
errors = await bucket.update_batch("py-example", batch)
assert not errors


if __name__ == "__main__":
import asyncio

asyncio.run(main())

Deleting Data​

The ReductStore API allows you to delete specific records from an entry, an entire entry, or an entire bucket. You can do this using the Client SDKs, the Reduct CLI, or the HTTP API.

Deleting Entry or Bucket​

The following examples show how to delete the entire entry or the entire bucket:


from reduct import Client, Bucket


async def main():
# Create a client with the base URL and API token
async with Client("http://localhost:8383", api_token="my-token") as client:
# Get bucket to remove
bucket: Bucket = await client.get_bucket("bucket-to-remove")

# Delete only entry with name "example-entry"
await bucket.remove_entry("example-entry")

# Remove entire bucket
await bucket.remove()


if __name__ == "__main__":
import asyncio

asyncio.run(main())

Deleting Specific Records​

You can remove a single record from an entry or a set of records by specifying their timestamps.

from time import time

from reduct import Client, Bucket, Batch


async def main():
# Create a client with the base URL and API token
async with Client("http://localhost:8383", api_token="my-token") as client:
bucket: Bucket = await client.create_bucket("my-bucket", exist_ok=True)

# Send some records to the "py-example"
ts = time()
await bucket.write(
"py-example",
b"Some binary data",
ts
)
await bucket.write(
"py-example",
b"Some binary data",
ts + 1
)

# Delete a single record
await bucket.remove_record("py-example", ts)

# Delete a batch of records
batch = Batch()
batch.add(ts) # already deleted, so this error will be in the errors map
batch.add(ts + 1)

errors = await bucket.remove_batch("py-example", batch)
assert len(errors) == 1
print(errors)

if __name__ == "__main__":
import asyncio

asyncio.run(main())

Deleting Records in a Time Range​

You can delete records in a specific time range by specifying the start and end timestamps, and you can use query parameters to filter the records:

ParameterDescriptionTypeDefault
startRemove records fromTimestampThe timestamp of the first record in the entry
endRemove records untilTimestampThe timestamp of the last record in the entry
whenConditional queryJSON-like objectNo condition
each_sRemove a record every S secondsFloatDisabled
each_nRemove only every N recordIntegerDisabled

All the listed parameters are the same as the query parameters for the query method. Read more about the querying data in the Querying Data guide.

The following examples show how to delete records in a specific time range:

from time import time

from reduct import Client, Bucket, Batch


async def main():
# Create a client with the base URL and API token
async with Client("http://localhost:8383", api_token="my-token") as client:
bucket: Bucket = await client.create_bucket("my-bucket", exist_ok=True)

# Send some records to the "py-example"
ts = time()
await bucket.write(
"py-example",
b"Some binary data",
ts
)
await bucket.write(
"py-example",
b"Some binary data",
ts + 1
)

# Delete all records within a time range
removed_records = await bucket.remove_query("py-example", ts, ts + 2)
assert removed_records == 2

# You can also delete all records with a specific label
await bucket.remove_query("py-example", ts, ts + 2, when={"&key1": {"$eq": "value1"}})

# Or each N-th record
await bucket.remove_query("py-example", ts, ts + 2, each_n=2)

if __name__ == "__main__":
import asyncio

asyncio.run(main())
warning

Deleting records in a time range is a heavy operation and may take a long time to complete because it copies the retained records to new blocks and deletes the old ones.

Renaming Entries​

An entry can be renamed using the SDKs, CLI client, Web Console, or REST API. A client must have write permission to a bucket to rename its entries if the authorization is enabled.

#!/bin/bash
set -e -x

reduct-cli alias add local -L http://localhost:8383 -t "my-token"

# Rename the entry entry_1 to entry_2 in the bucket example-bucket
reduct-cli bucket rename --only-entry entry_1 local/example-bucket entry_2