Writing Data¶
polars-redis provides write functions for six Redis data types: hashes, JSON, strings, sets, lists, and sorted sets.
Writing Hashes¶
write_hashes writes DataFrame rows as Redis hashes:
import polars as pl
import polars_redis as redis
df = pl.DataFrame({
"_key": ["user:1", "user:2"],
"name": ["Alice", "Bob"],
"age": [30, 25],
})
count = redis.write_hashes(df, "redis://localhost:6379")
print(f"Wrote {count} hashes")
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
df |
DataFrame | required | Data to write |
url |
str | required | Redis connection URL |
key_column |
str | None | "_key" |
Column with Redis keys |
ttl |
int | None | None |
TTL in seconds |
key_prefix |
str | "" |
Prefix for all keys |
if_exists |
str | "replace" |
How to handle existing keys |
Writing JSON¶
write_json writes DataFrame rows as RedisJSON documents:
df = pl.DataFrame({
"_key": ["doc:1", "doc:2"],
"title": ["Hello", "World"],
"views": [100, 200],
})
count = redis.write_json(df, "redis://localhost:6379")
Parameters are identical to write_hashes.
Writing Strings¶
write_strings writes DataFrame rows as Redis strings:
df = pl.DataFrame({
"_key": ["counter:1", "counter:2"],
"value": ["100", "200"],
})
count = redis.write_strings(
df,
"redis://localhost:6379",
value_column="value",
)
String-specific Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
value_column |
str | "value" |
Column with values to write |
Key Generation¶
From Column¶
Use an existing column as keys:
df = pl.DataFrame({
"id": ["user:1", "user:2"],
"name": ["Alice", "Bob"],
})
redis.write_hashes(df, url, key_column="id")
Auto-generated¶
Generate keys from row indices:
df = pl.DataFrame({
"name": ["Alice", "Bob", "Carol"],
"age": [30, 25, 35],
})
# Keys will be "user:0", "user:1", "user:2"
redis.write_hashes(
df,
url,
key_column=None,
key_prefix="user:",
)
With Prefix¶
Add a prefix to existing keys:
df = pl.DataFrame({
"_key": ["1", "2"],
"name": ["Alice", "Bob"],
})
# Keys will be "user:1", "user:2"
redis.write_hashes(df, url, key_prefix="user:")
Write Modes¶
The if_exists parameter controls behavior for existing keys:
Replace (default)¶
Delete existing keys before writing:
This ensures a clean write - existing hash fields not in the DataFrame are removed.
Fail¶
Skip keys that already exist:
Only new keys are written. Existing keys are left unchanged.
Append¶
Merge new fields into existing hashes:
Existing fields are overwritten, but fields not in the DataFrame are preserved.
Note
For JSON and strings, append behaves the same as replace since these types don't have partial updates.
TTL (Time-to-Live)¶
Set expiration on written keys:
# Expire in 1 hour (3600 seconds)
redis.write_hashes(df, url, ttl=3600)
# Expire in 1 day
redis.write_hashes(df, url, ttl=86400)
# No expiration (default)
redis.write_hashes(df, url, ttl=None)
Writing Sets¶
write_sets writes DataFrame rows as Redis sets:
df = pl.DataFrame({
"_key": ["tags:post:1", "tags:post:2"],
"member": ["python", "redis"],
})
count = redis.write_sets(df, "redis://localhost:6379")
Multiple members per key can be written by having multiple rows with the same key:
df = pl.DataFrame({
"_key": ["tags:post:1", "tags:post:1", "tags:post:1"],
"member": ["python", "redis", "polars"],
})
# Creates one set with 3 members
count = redis.write_sets(df, url)
Set-specific Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
member_column |
str | "member" |
Column with member values |
Writing Lists¶
write_lists writes DataFrame rows as Redis lists:
df = pl.DataFrame({
"_key": ["queue:tasks", "queue:tasks", "queue:tasks"],
"element": ["task1", "task2", "task3"],
})
count = redis.write_lists(df, "redis://localhost:6379")
Elements are written in DataFrame row order using RPUSH.
List-specific Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
element_column |
str | "element" |
Column with element values |
Writing Sorted Sets¶
write_zsets writes DataFrame rows as Redis sorted sets:
df = pl.DataFrame({
"_key": ["leaderboard:game1", "leaderboard:game1", "leaderboard:game1"],
"member": ["alice", "bob", "carol"],
"score": [100.0, 85.5, 92.0],
})
count = redis.write_zsets(df, "redis://localhost:6379")
Sorted Set-specific Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
member_column |
str | "member" |
Column with member values |
score_column |
str | "score" |
Column with score values |
Batch Pipelining¶
Write operations are automatically pipelined in batches of 1000 keys for performance. This reduces round-trips to Redis.
Return Value¶
All write functions return the number of keys successfully written:
Detailed Error Handling¶
For production workflows where you need granular error reporting, use the _detailed variants of write functions. These return a WriteResult object with per-key success/failure information.
WriteResult Class¶
result = redis.write_hashes_detailed(df, "redis://localhost:6379")
# Check counts
result.keys_written # Number of keys successfully written
result.keys_failed # Number of keys that failed
result.keys_skipped # Number of keys skipped (when if_exists="fail")
# Access key lists
result.succeeded_keys # List of successfully written keys
result.failed_keys # List of keys that failed
# Get error details
result.errors # Dict mapping failed keys to error messages
# Check for complete success
if result.is_complete_success():
print("All keys written successfully")
Basic Usage¶
import polars as pl
import polars_redis as redis
df = pl.DataFrame({
"_key": ["user:1", "user:2", "user:3"],
"name": ["Alice", "Bob", "Charlie"],
"age": [30, 25, 35],
})
result = redis.write_hashes_detailed(df, "redis://localhost:6379")
print(f"Wrote {result.keys_written} keys")
print(f"Failed: {result.keys_failed}")
print(f"Skipped: {result.keys_skipped}")
if not result.is_complete_success():
for key, error in result.errors.items():
print(f" {key}: {error}")
Retry Pattern¶
The detailed result enables retry logic for failed keys:
import polars as pl
import polars_redis as redis
def write_with_retry(df, url, max_retries=3):
"""Write with automatic retry for failed keys."""
remaining = df
total_written = 0
for attempt in range(max_retries):
result = redis.write_hashes_detailed(remaining, url)
total_written += result.keys_written
if result.is_complete_success():
break
if result.keys_failed > 0:
print(f"Attempt {attempt + 1}: {result.keys_failed} failures")
# Filter to only failed keys for retry
remaining = remaining.filter(
pl.col("_key").is_in(result.failed_keys)
)
return total_written
# Usage
df = pl.DataFrame({
"_key": ["user:1", "user:2", "user:3"],
"name": ["Alice", "Bob", "Charlie"],
"age": [30, 25, 35],
})
written = write_with_retry(df, "redis://localhost:6379")
print(f"Successfully wrote {written} keys")
When to Use Detailed Functions¶
Use write_hashes_detailed() when you need to:
- Implement retry logic: Retry only the keys that failed
- Log specific failures: Record which keys failed and why
- Partial success handling: Accept partial writes in non-critical workflows
- Debugging: Identify problematic keys during development
For simple scripts where you just need a count, the regular write_hashes() is sufficient.