Determine ULID prefixes for date ranges
Project description
ULID Dates
A Python utility to determine ULID prefixes for date ranges.
This can be useful for querying databases or logs for ULIDs that fall within a specific time period.
For example by finding the prefixes for the start and end of a time range, you can efficiently scan for records within that range.
If id is a ULID, you can then fine items between two time prefixes ... WHERE id >= 'start_prefix' AND id < 'end_prefix'.
Installation
Install the package using pip:
pip install ulid-dates
Alternatively, using uv:
uv pip install ulid-dates
Usage
Basic Usage
from datetime import datetime, timedelta
from ulid_dates import ulid_prefix_range_for_dates
start_date = datetime(2023, 1, 1)
end_date = start_date + timedelta(days=1)
start_prefix, end_prefix = ulid_prefix_range_for_dates(start_date, end_date)
print(f"ULID prefix for {start_date}: {start_prefix}")
print(f"ULID prefix for {end_date}: {end_prefix}")
Advanced Usage: Querying a DynamoDB GSI
A use case for this library is to query a database for records that have UUIDs within a specific time range. If you are using ULIDs as sort keys in a DynamoDB Global Secondary Index (GSI), you can use the generated prefixes to efficiently query for records created within a certain period.
Here is an example of how you might query a GSI in a DynamoDB table where logs for orders are stored within the PKI but with a common lookup value and a sort that contains a UUID.
import boto3
from boto3.dynamodb.conditions import Key
from datetime import datetime, timedelta
from ulid_dates import ulid_prefix_range_for_dates
# 1. Configure DynamoDB table and GSI query parameters
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('my-application-single-table')
gsi_name = 'lookup-index'
# 2. Generate the ULID prefixes for the date range
start_date = datetime.now() - timedelta(days=7)
end_date = datetime.now()
start_prefix, end_prefix = ulid_prefix_range_for_dates(start_date, end_date)
# 3. Query the GSI using the ULID prefixes
# This assumes the GSI partition key is 'logs' and the sort key is 'created_at' (a ULID).
response = table.query(
IndexName=gsi_name,
KeyConditionExpression=Key('lookup').eq('Order#Logs#')
& Key('sort').between(
f"Order#Log#{start_prefix}",
f"Order#Log#{end_prefix}"
)
)
# 4. Print the results
items = response.get('Items', [])
print(f"Found {len(items)} logs.")
Development
To set up the development environment:
- Clone the repository.
- Create a virtual environment and activate it.
- Install the dependencies in editable mode.
Using pip:
pip install -e .[dev]
Alternatively, using uv:
uv pip install -e .[dev]
Running Tests
To run the tests, use pytest:
pytest
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 Distribution
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 ulid_dates-0.2.0.tar.gz.
File metadata
- Download URL: ulid_dates-0.2.0.tar.gz
- Upload date:
- Size: 5.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
220ebb787d882b9bebee592bbc4f222b6712c0fc64124fdb028f0cd84c76dab0
|
|
| MD5 |
7b57fce5a5ad05f9c74141102ab6e97b
|
|
| BLAKE2b-256 |
1bb79f4a8d4305de0e886523a532f89526b45db2a3fa5349c757268f07c5818d
|
File details
Details for the file ulid_dates-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ulid_dates-0.2.0-py3-none-any.whl
- Upload date:
- Size: 4.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45502dddbf54376e48446d293517eeefb5c3a2c5830cf15b5f6c85822e17caa8
|
|
| MD5 |
e96ab77ffccf5a8c993182016cb7ea8b
|
|
| BLAKE2b-256 |
cdb29e4bdd79ca3b64719f82dfe6fd2b923e48730fff94e90eda504f74ac4c50
|