litestar-stores

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Stores

存储

Use this skill when the problem is Litestar's interchangeable key-value store layer, not relational data modeling.
当问题涉及Litestar可互换的键值存储层而非关系型数据建模时,使用本技能。

Execution Workflow

执行工作流

  1. Decide whether the feature really belongs in a Litestar store: cache, session, rate limit, or other ephemeral/shared key-value state.
  2. Choose the backend based on process model, durability, latency, and cleanup needs.
  3. Decide whether stores should be wired explicitly by name, created lazily through
    StoreRegistry
    , or derived from a namespaced default factory.
  4. Define key naming, namespacing boundaries, TTL policy, and any renewal-on-read behavior.
  5. Wire integrations such as response caching, sessions, or rate limiting to named stores intentionally.
  6. Plan cleanup and shutdown behavior, especially for
    FileStore
    expiry cleanup and Redis client ownership.
  7. Verify expiry, isolation, and multi-worker behavior before relying on the store in production.
  1. 判断功能是否确实属于Litestar存储范畴:缓存、会话、速率限制或其他临时/共享键值状态。
  2. 根据进程模型、持久性、延迟及清理需求选择后端。
  3. 决定存储是应按名称显式连接、通过
    StoreRegistry
    延迟创建,还是从命名空间默认工厂派生。
  4. 定义键命名规则、命名空间边界、TTL策略及任何读取续期行为。
  5. 有意地将响应缓存、会话或速率限制等集成与指定存储关联。
  6. 规划清理与关闭行为,尤其针对
    FileStore
    的过期清理和Redis客户端所有权管理。
  7. 在生产环境依赖存储前,验证过期机制、隔离性及多 worker 行为。

Core Rules

核心规则

  • Treat stores as interchangeable key-value infrastructure, not as ad hoc object persistence.
  • Design for the store contract: values are bytes-oriented, even when a backend has extra convenience behavior.
  • Keep namespacing and store names intentional before using bulk operations like
    delete_all()
    .
  • Match TTL policy to the feature: absolute expiry, renewal on access, or no expiry.
  • Do not assume all backends clean up expired data the same way.
  • Prefer named stores or namespaced stores over one flat keyspace shared by unrelated features.
  • Use a distributed backend for any state that must survive across workers or instances.
  • Make store ownership explicit when external clients or filesystem paths need lifecycle management.
  • 将存储视为可互换的键值基础设施,而非临时对象持久化工具。
  • 依据存储契约设计:值以字节为导向,即使后端具备额外便捷功能。
  • 在使用
    delete_all()
    等批量操作前,确保命名空间和存储名称的合理性。
  • 使TTL策略与功能匹配:绝对过期、访问续期或永不过期。
  • 不要假设所有后端清理过期数据的方式相同。
  • 优先使用命名存储或命名空间存储,而非由无关功能共享的单一扁平键空间。
  • 对于必须跨worker或实例存活的状态,使用分布式后端。
  • 当外部客户端或文件系统路径需要生命周期管理时,明确存储所有权。

Decision Guide

决策指南

  • Use
    MemoryStore
    for simple single-process caching or low-stakes ephemeral state with minimal overhead.
  • Use
    FileStore
    when persistence on disk matters more than speed, especially for larger or longer-lived data.
  • Use
    RedisStore
    for general production-grade shared state, multi-worker communication, and namespaced bulk operations.
  • Use
    ValkeyStore
    when you want Redis-style behavior on Valkey; Litestar documents it as equivalent in practice to Redis for these store concerns.
  • Use explicit
    stores={...}
    mappings when integrations must resolve known store names.
  • Use
    StoreRegistry(default_factory=...)
    when undefined store names should be created lazily from one policy.
  • Use
    with_namespace()
    when one underlying backend should safely host multiple isolated logical stores.
  • Use
    litestar-caching
    alongside this skill when response-cache TTL, cache keys, or cache filtering are the main design problem.
  • 使用
    MemoryStore
    实现简单单进程缓存或低风险临时状态,开销最小。
  • 当磁盘持久性比速度更重要时,使用
    FileStore
    ,尤其适用于较大或生命周期较长的数据。
  • 使用
    RedisStore
    实现通用生产级共享状态、多worker通信及命名空间批量操作。
  • 当希望在Valkey上实现Redis式行为时,使用
    ValkeyStore
    ;根据Litestar文档,在存储相关场景中,它与Redis实际等效。
  • 当集成必须解析已知存储名称时,使用显式
    stores={...}
    映射。
  • 当未定义的存储名称应通过单一策略延迟创建时,使用
    StoreRegistry(default_factory=...)
  • 当一个底层后端需要安全托管多个独立逻辑存储时,使用
    with_namespace()
  • 当响应缓存TTL、缓存键或缓存过滤是主要设计问题时,结合使用
    litestar-caching
    与本技能。

Reference Files

参考文件

Read only the sections you need:
  • For store operations, bytes-vs-string behavior, TTL renewal, and cleanup mechanics, read references/store-operations-and-data.md.
  • For backend selection tradeoffs and backend-specific operational notes, read references/backend-selection-and-lifecycle.md.
  • For
    StoreRegistry
    , namespacing, integration wiring, and default-factory patterns, read references/registry-and-namespacing.md.
仅阅读所需章节:
  • 如需了解存储操作、字节与字符串行为、TTL续期及清理机制,请阅读references/store-operations-and-data.md
  • 如需了解后端选择权衡及后端特定操作说明,请阅读references/backend-selection-and-lifecycle.md
  • 如需了解
    StoreRegistry
    、命名空间、集成连接及默认工厂模式,请阅读references/registry-and-namespacing.md

Store Fundamentals

存储基础

Litestar store operations center around a small async API:
  • set(key, value, expires_in=...)
  • get(key, renew_for=...)
  • delete(key)
  • delete_all()
  • exists(key)
  • expires_in(key)
Key behavioral rules from the docs:
  • Stores generally accept bytes and return bytes.
  • set()
    also accepts strings for convenience, but
    get()
    still returns bytes.
  • expires_in
    can be set when writing data.
  • renew_for
    can be passed to
    get()
    to extend TTL on access when the backend supports expiry for that key.
  • If
    delete()
    is called for a missing key, it is a no-op.
Litestar存储操作围绕一个小型异步API展开:
  • set(key, value, expires_in=...)
  • get(key, renew_for=...)
  • delete(key)
  • delete_all()
  • exists(key)
  • expires_in(key)
文档中的关键行为规则:
  • 存储通常接受字节并返回字节。
  • 为方便起见,
    set()
    也接受字符串,但
    get()
    仍返回字节。
  • 写入数据时可设置
    expires_in
  • 当后端支持该键的过期机制时,可向
    get()
    传递
    renew_for
    以在访问时延长TTL。
  • 若对不存在的键调用
    delete()
    ,该操作将被忽略。

Backend Selection

后端选择

MemoryStore

MemoryStore

  • Default Litestar store.
  • Lowest overhead.
  • No persistence.
  • Not thread-safe or multiprocess-safe.
  • Avoid for multi-worker or multi-instance shared state.
  • Litestar默认存储。
  • 开销最低。
  • 无持久性。
  • 非线程安全或多进程安全。
  • 避免用于多worker或多实例共享状态。

FileStore

FileStore

  • Persists data on disk.
  • Slower than memory-backed approaches.
  • Good fit when data volume, longevity, or backupability matters.
  • Supports namespacing via sub-paths.
  • Expired entries are not proactively removed; plan
    delete_expired()
    calls.
  • 将数据持久化到磁盘。
  • 比内存型方案速度慢。
  • 适用于数据量、生命周期或可备份性较为重要的场景。
  • 通过子路径支持命名空间。
  • 不会主动移除过期条目;需规划
    delete_expired()
    调用。

RedisStore

RedisStore

  • Suitable for almost all applications that need shared or durable-ish key-value infrastructure.
  • Supports namespacing and safe namespace-scoped
    delete_all()
    .
  • Native expiry behavior comes from Redis itself.
  • Good fit for multi-worker deployments, sessions, rate limiting, and shared cache state.
  • 适用于几乎所有需要共享或准持久键值基础设施的应用。
  • 支持命名空间及安全的命名空间范围
    delete_all()
    操作。
  • 原生过期行为由Redis本身提供。
  • 适用于多worker部署、会话、速率限制及共享缓存状态。

ValkeyStore

ValkeyStore

  • Same practical guidance as
    RedisStore
    according to the Litestar docs.
  • Supports namespacing.
  • Use when the deployment standard is Valkey rather than Redis.
  • 根据Litestar文档,其实践指导与
    RedisStore
    相同。
  • 支持命名空间。
  • 当部署标准为Valkey而非Redis时使用。

TTL and Expiry Semantics

TTL与过期语义

  • Use
    expires_in
    on
    set()
    for absolute expiration.
  • Use
    renew_for
    on
    get()
    for sliding expiration or access-based renewal, such as sessions or LRU-like behavior.
  • Redis/Valkey use native expiry mechanisms.
  • FileStore
    deletes expired values only when they are accessed or when
    delete_expired()
    is run explicitly.
  • MemoryStore
    and
    FileStore
    may retain expired data until access or cleanup; do not treat TTL as equivalent to immediate background deletion on those backends.
  • set()
    上使用
    expires_in
    实现绝对过期。
  • get()
    上使用
    renew_for
    实现滑动过期或基于访问的续期,例如会话或类LRU行为。
  • Redis/Valkey使用原生过期机制。
  • FileStore
    仅在访问条目或显式运行
    delete_expired()
    时删除过期值。
  • MemoryStore
    FileStore
    可能保留过期数据直到访问或清理;不要将这些后端的TTL等同于即时后台删除。

Namespacing

命名空间

  • Namespacing exists to make shared backends safe for multiple logical purposes.
  • with_namespace()
    creates a child store whose operations affect only that namespace and its children.
  • This is especially important before using
    delete_all()
    .
  • RedisStore
    uses
    LITESTAR
    as the default namespace.
  • Passing
    namespace=None
    disables Redis namespacing and makes
    delete_all()
    unavailable.
  • File-backed namespacing uses sub-paths under the parent store path.
  • 命名空间的作用是使共享后端可安全用于多种逻辑用途。
  • with_namespace()
    创建一个子存储,其操作仅影响该命名空间及其子命名空间。
  • 在使用
    delete_all()
    前,这一点尤为重要。
  • RedisStore
    使用
    LITESTAR
    作为默认命名空间。
  • 传递
    namespace=None
    会禁用Redis命名空间,并使
    delete_all()
    不可用。
  • 文件型命名空间使用父存储路径下的子路径。

Store Registry

存储注册表

  • Litestar.stores
    exposes the application's
    StoreRegistry
    .
  • A registry can start from a mapping of store names to store instances.
  • app.stores.get(name)
    returns a registered store or creates one via the registry's
    default_factory
    .
  • The default registry factory returns a new
    MemoryStore
    for unknown names.
  • You can pass a custom
    StoreRegistry
    to change that behavior globally.
  • StoreRegistry.register(name, store, allow_override=False)
    is the explicit registration path when dynamic creation is not enough.
  • Litestar.stores
    暴露应用的
    StoreRegistry
  • 注册表可从存储名称到存储实例的映射开始初始化。
  • app.stores.get(name)
    返回已注册的存储,或通过注册表的
    default_factory
    创建一个新存储。
  • 默认注册表工厂会为未知名称返回新的
    MemoryStore
  • 您可以传递自定义
    StoreRegistry
    来全局更改此行为。
  • 当动态创建不足以满足需求时,
    StoreRegistry.register(name, store, allow_override=False)
    是显式注册的方式。

Integration Wiring

集成连接

Litestar integrations resolve stores by name through the registry. Important consequences:
  • Response caching defaults to the
    response_cache
    store name unless configured otherwise.
  • Session middleware defaults to the
    sessions
    store name unless configured otherwise.
  • Rate limiting resolves its store by name as well.
  • These names are conventions, not magic constants; you can point integrations at other names with their own config.
  • One registry can host multiple backends for different integrations, or one namespaced backend can serve many integrations through the default factory.
Litestar集成通过注册表按名称解析存储。重要结论:
  • 响应缓存默认使用
    response_cache
    存储名称,除非另行配置。
  • 会话中间件默认使用
    sessions
    存储名称,除非另行配置。
  • 速率限制也按名称解析其存储。
  • 这些名称是约定而非魔法常量;您可以通过各自的配置将集成指向其他名称。
  • 一个注册表可以为不同集成托管多个后端,或一个命名空间后端可通过默认工厂为多个集成提供服务。

Data Contract and Serialization Boundary

数据契约与序列化边界

  • The portable store contract is bytes-based.
  • Do not rely on backend-specific object behavior if the store may be swapped later.
  • MemoryStore
    can technically hold arbitrary Python objects because it stores directly in memory, but Litestar's documented interface does not guarantee that portability.
  • Serialize structured values explicitly before storing when backend interchangeability matters.
  • 可移植存储契约基于字节。
  • 如果存储可能在后续被替换,不要依赖后端特定的对象行为。
  • MemoryStore
    理论上可以存储任意Python对象,因为它直接在内存中存储,但Litestar的文档接口不保证这种可移植性。
  • 当后端可互换性很重要时,在存储前显式序列化结构化值。

Cleanup and Lifetime

清理与生命周期

  • Call
    delete_expired()
    periodically for
    MemoryStore
    and especially
    FileStore
    when stale entries would otherwise accumulate.
  • FileStore.delete_expired()
    is a good startup or maintenance task when the directory is long-lived.
  • If you create a
    RedisStore
    directly around your own Redis client and do not use the helper lifecycle, you are responsible for shutting that client down.
  • Prefer
    RedisStore.with_client(...)
    or explicit ownership flags when you want Litestar/the store to manage the client lifecycle.
  • 定期为
    MemoryStore
    (尤其
    FileStore
    )调用
    delete_expired()
    ,以避免过期条目累积。
  • 当目录生命周期较长时,
    FileStore.delete_expired()
    是一个合适的启动或维护任务。
  • 如果您直接围绕自己的Redis客户端创建
    RedisStore
    且未使用辅助生命周期管理,则需负责关闭该客户端。
  • 当希望Litestar/存储管理客户端生命周期时,优先使用
    RedisStore.with_client(...)
    或显式所有权标志。

Recommended Defaults

推荐默认配置

  • Keep
    MemoryStore
    only for local development, single-process apps, or low-stakes ephemeral state.
  • Prefer Redis or Valkey for shared cache, sessions, and rate limits in production.
  • Use explicit store names for integrations when different backends serve different concerns.
  • Use one root namespaced Redis/Valkey store when you want shared infrastructure with isolated logical children.
  • Serialize structured data to bytes or strings intentionally rather than leaning on
    MemoryStore
    object storage.
  • Run expiry cleanup on file-backed stores as a deliberate maintenance task.
  • MemoryStore
    仅用于本地开发、单进程应用或低风险临时状态。
  • 生产环境中,优先使用Redis或Valkey实现共享缓存、会话和速率限制。
  • 当不同后端服务于不同需求时,为集成使用显式存储名称。
  • 当需要共享基础设施且具备独立逻辑子存储时,使用一个根命名空间Redis/Valkey存储。
  • 有意地将结构化数据序列化为字节或字符串,而非依赖
    MemoryStore
    的对象存储功能。
  • 将文件型存储的过期清理作为一项刻意的维护任务执行。

Example Pattern

示例模式

python
from litestar import Litestar, get
from litestar.config.response_cache import ResponseCacheConfig
from litestar.middleware.rate_limit import RateLimitConfig
from litestar.middleware.session.server_side import ServerSideSessionConfig
from litestar.stores.redis import RedisStore
from litestar.stores.registry import StoreRegistry


root_store = RedisStore.with_client()


@get("/cached", cache=True, sync_to_thread=False)
def cached_handler() -> str:
    return "hello"


app = Litestar(
    [cached_handler],
    stores=StoreRegistry(default_factory=root_store.with_namespace),
    response_cache_config=ResponseCacheConfig(store="response_cache"),
    middleware=[
        ServerSideSessionConfig(store="sessions").middleware,
        RateLimitConfig(rate_limit=("second", 10), store="rate_limit").middleware,
    ],
)
python
from litestar import Litestar, get
from litestar.config.response_cache import ResponseCacheConfig
from litestar.middleware.rate_limit import RateLimitConfig
from litestar.middleware.session.server_side import ServerSideSessionConfig
from litestar.stores.redis import RedisStore
from litestar.stores.registry import StoreRegistry


root_store = RedisStore.with_client()


@get("/cached", cache=True, sync_to_thread=False)
def cached_handler() -> str:
    return "hello"


app = Litestar(
    [cached_handler],
    stores=StoreRegistry(default_factory=root_store.with_namespace),
    response_cache_config=ResponseCacheConfig(store="response_cache"),
    middleware=[
        ServerSideSessionConfig(store="sessions").middleware,
        RateLimitConfig(rate_limit=("second", 10), store="rate_limit").middleware,
    ],
)

Anti-Patterns

反模式

  • Using
    MemoryStore
    for state that must be shared across workers or processes.
  • Treating stores as a substitute for relational or queryable persistence.
  • Storing arbitrary Python objects because
    MemoryStore
    happens to allow it.
  • Using one flat keyspace and then calling
    delete_all()
    without namespaces or isolated store names.
  • Assuming expired entries disappear immediately on
    FileStore
    or
    MemoryStore
    .
  • Forgetting to clean up filesystem-backed expired entries.
  • Passing
    namespace=None
    to Redis and then expecting safe namespace-scoped bulk deletion.
  • Assuming integration store names are fixed and unchangeable instead of config-driven.
  • Adding Memcached as if it were a supported drop-in backend.
  • 使用
    MemoryStore
    存储必须跨worker或进程共享的状态。
  • 将存储视为关系型或可查询持久化的替代方案。
  • 因为
    MemoryStore
    允许就存储任意Python对象。
  • 使用单一扁平键空间,然后在未使用命名空间或独立存储名称的情况下调用
    delete_all()
  • 假设过期条目会立即从
    FileStore
    MemoryStore
    中消失。
  • 忘记清理文件型存储的过期条目。
  • 为Redis传递
    namespace=None
    ,然后期望安全的命名空间范围批量删除。
  • 假设集成存储名称是固定且不可更改的,而非由配置驱动。
  • 将Memcached视为受支持的直接替换后端添加。

Validation Checklist

验证检查清单

  • Confirm the selected backend matches process topology and durability requirements.
  • Confirm values are serialized in a backend-portable way when portability matters.
  • Confirm TTL behavior matches actual backend semantics, including renewal-on-read where used.
  • Confirm file- or memory-backed stores have an explicit expired-entry cleanup strategy when needed.
  • Confirm namespacing or store naming prevents cross-feature collisions and unsafe bulk deletion.
  • Confirm
    app.stores.get(name)
    resolves the intended store for each integration.
  • Confirm cache, sessions, and rate limiting are pointed at the intended store names.
  • Confirm Redis/Valkey client shutdown ownership is explicit.
  • Confirm multi-worker deployments do not depend on
    MemoryStore
    .
  • 确认所选后端符合进程拓扑和持久性要求。
  • 当可移植性很重要时,确认值以后端可移植的方式序列化。
  • 确认TTL行为与实际后端语义匹配,包括所用的读取续期机制。
  • 当需要时,确认文件型或内存型存储具备明确的过期条目清理策略。
  • 确认命名空间或存储命名可防止跨功能冲突及不安全的批量删除。
  • 确认
    app.stores.get(name)
    为每个集成解析到预期的存储。
  • 确认缓存、会话和速率限制指向预期的存储名称。
  • 确认Redis/Valkey客户端关闭所有权明确。
  • 确认多worker部署不依赖
    MemoryStore

Cross-Skill Handoffs

跨技能交接

  • Use
    litestar-caching
    for response-cache TTL, key-builder, and cache-filter strategy.
  • Use
    litestar-authentication
    or
    litestar-security
    when session/auth data is the main concern.
  • Use
    litestar-middleware
    when rate limit or session middleware behavior is the primary task.
  • Use
    litestar-app-setup
    for startup/shutdown cleanup hooks around store maintenance.
  • Use
    litestar-testing
    to verify expiry, integration wiring, and multi-backend behavior.
  • 使用
    litestar-caching
    处理响应缓存TTL、键构建器及缓存过滤策略。
  • 当会话/认证数据是主要关注点时,使用
    litestar-authentication
    litestar-security
  • 当速率限制或会话中间件行为是主要任务时,使用
    litestar-middleware
  • 使用
    litestar-app-setup
    设置围绕存储维护的启动/关闭清理钩子。
  • 使用
    litestar-testing
    验证过期机制、集成连接及多后端行为。

Litestar References

Litestar参考链接