Indexes¶
DynamoDB supports two types of secondary indexes: Global Secondary Indexes (GSI) and Local Secondary Indexes (LSI). Both are defined via the indexes argument to @table().
Global Secondary Index (GSI)¶
A GSI lets you query on a different partition key than the table's primary key.
from aiodynamodb import DynamoModel, HashKey, RangeKey, table
from aiodynamodb.models import GSI
order_by_status = GSI(
name="order_by_status",
hash_key="status",
range_key="created_at",
)
@table("orders", indexes=[order_by_status])
class Order(DynamoModel):
order_id: HashKey[str]
created_at: RangeKey[str]
status: str
total: int
GSI parameters¶
| Parameter | Type | Description |
|---|---|---|
name |
str |
Index name (must be unique among GSIs on this table) |
hash_key |
str |
Partition key field for the index |
range_key |
str | None |
Sort key field for the index (optional) |
projection |
str |
"ALL" (default), "KEYS_ONLY", or "INCLUDE" |
non_key_attributes |
list[str] | None |
Projected attributes when projection="INCLUDE" |
provisioned_throughput |
ProvisionedThroughputTypeDef | None |
Throughput for provisioned mode |
on_demand_throughput |
OnDemandThroughputTypeDef | None |
On-demand throughput configuration |
warm_throughput |
WarmThroughputTypeDef | None |
Warm throughput configuration |
Local Secondary Index (LSI)¶
An LSI shares the table's partition key but uses a different sort key. It must be created at table creation time.
from aiodynamodb import HashKey, RangeKey
from aiodynamodb.models import LSI
order_lsi = LSI(
name="order_by_total",
range_key="total",
)
@table("orders", indexes=[order_lsi])
class Order(DynamoModel):
order_id: HashKey[str]
created_at: RangeKey[str]
total: int
LSI parameters¶
| Parameter | Type | Description |
|---|---|---|
name |
str |
Index name (must be unique among LSIs on this table) |
range_key |
str |
Sort key field for the index |
projection |
str |
"ALL" (default), "KEYS_ONLY", or "INCLUDE" |
non_key_attributes |
list[str] | None |
Projected attributes when projection="INCLUDE" |
Combining GSI and LSI¶
from aiodynamodb import HashKey, RangeKey
from aiodynamodb.models import GSI, LSI
order_gsi = GSI(name="order_gsi", hash_key="order_id", range_key="total")
order_lsi = LSI(name="order_lsi", range_key="total")
@table("orders", indexes=[order_gsi, order_lsi])
class Order(DynamoModel):
order_id: HashKey[str]
created_at: RangeKey[str]
total: int
Index names must be unique within each index type (GSI names must be unique, LSI names must be unique).
Querying an index¶
Pass index_name to db.query():
from boto3.dynamodb.conditions import Key
# Query a GSI
async for page in db.query(
Order,
index_name="order_gsi",
key_condition_expression=Key("order_id").eq("o1"),
):
for item in page.items:
print(item)
from boto3.dynamodb.conditions import Attr, Key
# Query an LSI with a filter
async for page in db.query(
Order,
index_name="order_lsi",
key_condition_expression=Key("order_id").eq("o1"),
filter_expression=Attr("total").gte(200),
):
print(page.items)
See the Query guide for the full query() API.