跳转至

SQLAlchemy CouchDB - 高级功能文档

版本: 0.1.0 (Phase 1 增强) 日期: 2025-11-03 状态: ✅ 生产可用


📚 目录

  1. 错误处理增强
  2. 查询缓存
  3. 高级查询支持
  4. 索引管理
  5. 视图管理
  6. 性能优化建议

1. 错误处理增强

重试机制

自动重试网络错误、超时等临时性故障。

基础用法

from sqlalchemy import create_engine
from sqlalchemy_couchdb.retry import RetryConfig

# 配置重试策略
retry_config = RetryConfig(
    max_retries=3,          # 最大重试3次
    retry_delay=0.5,        # 初始延迟0.5秒
    backoff_factor=2.0,     # 每次延迟翻倍
    retry_on_status_codes=(502, 503, 504)  # 重试这些HTTP状态码
)

# 创建引擎时传入重试配置
engine = create_engine(
    'couchdb://admin:password@localhost:5984/mydb',
    connect_args={'retry_config': retry_config}
)

装饰器用法

from sqlalchemy_couchdb.retry import with_retry, RetryConfig

@with_retry(RetryConfig(max_retries=5))
def my_critical_operation():
    # 可能失败的操作
    return client.find({"type": "users"})

特性

  • ✅ 指数退避策略(避免服务器过载)
  • ✅ 可配置重试次数和延迟
  • ✅ 自定义重试状态码
  • ✅ 同步和异步支持

2. 查询缓存

LRU 缓存 + TTL

自动缓存查询结果,减少数据库访问。

启用缓存

from sqlalchemy_couchdb.client import SyncCouchDBClient

client = SyncCouchDBClient(
    host="localhost",
    port=5984,
    username="admin",
    password="password",
    database="mydb",
    enable_cache=True,     # 启用缓存
    cache_size=100,        # 缓存100个查询
    cache_ttl=300.0,       # 5分钟过期
)

使用缓存

# 第一次查询(从数据库)
results1 = client.find({"age": {"$gt": 25}}, use_cache=True)

# 第二次查询(从缓存,速度快!)
results2 = client.find({"age": {"$gt": 25}}, use_cache=True)

# 查看缓存统计
stats = client.cache.get_stats()
print(f"缓存命中率: {stats['hit_rate']}")
print(f"缓存大小: {stats['size']}/{stats['max_size']}")

缓存失效

# 清空所有缓存
client.cache.clear()

# 使特定表的缓存失效
client.cache.invalidate(table="users")

特性

  • ✅ LRU(最近最少使用)策略
  • ✅ TTL(生存时间)支持
  • ✅ 自动缓存失效(INSERT/UPDATE/DELETE 后)
  • ✅ 缓存统计信息

3. 高级查询支持

聚合函数

在客户端实现聚合功能(CouchDB 原生不支持)。

COUNT

from sqlalchemy_couchdb.advanced import QueryProcessor

# 查询数据
results = client.find({"type": "users"})

# 计数
total_count = QueryProcessor.count(results)
print(f"总用户数: {total_count}")

# 不同值计数
dept_count = QueryProcessor.count_distinct(results, "department")
print(f"部门数: {dept_count}")

SUM / AVG / MIN / MAX

# 求和
total_salary = QueryProcessor.sum(results, "salary")
print(f"工资总和: ${total_salary:,.2f}")

# 平均值
avg_salary = QueryProcessor.avg(results, "salary")
print(f"平均工资: ${avg_salary:,.2f}")

# 最小值和最大值
min_age = QueryProcessor.min(results, "age")
max_age = QueryProcessor.max(results, "age")
print(f"年龄范围: {min_age} - {max_age}")

GROUP BY

# 按部门分组,计算平均工资
grouped = QueryProcessor.group_by(
    results,
    group_fields=["department"],
    aggregate_func="avg",
    aggregate_field="salary"
)

for row in grouped:
    print(f"{row['department']}: ${row['avg_salary']:,.2f}")

DISTINCT

# 去重
unique_results = QueryProcessor.apply_distinct(results, ["name", "email"])

使用 CouchDB 视图实现聚合

对于大数据集,使用视图更高效:

from sqlalchemy_couchdb.advanced import AggregateQueryBuilder

# 创建统计视图
builder = AggregateQueryBuilder()

# 按部门计数
count_view = builder.create_count_view(
    design_doc="stats",
    view_name="count_by_department",
    group_field="department"
)

# 创建视图
client.view_manager.create_view(
    "stats",
    "count_by_department",
    count_view['map'],
    count_view['reduce']
)

# 查询视图
result = client.view_manager.query_view(
    "stats",
    "count_by_department",
    group=True
)

4. 索引管理

IndexManager

管理 CouchDB 索引的完整工具。

创建索引

# 获取索引管理器
index_mgr = client.index_manager

# 创建单字段索引
index_mgr.create_index(
    fields=["age"],
    name="idx_age"
)

# 创建复合索引
index_mgr.create_index(
    fields=["department", "salary"],
    name="idx_dept_salary"
)

列出索引

indexes = index_mgr.list_indexes()

for idx in indexes:
    print(f"索引名: {idx['name']}")
    print(f"字段: {idx['def']['fields']}")
    print(f"类型: {idx['type']}")

查找索引

# 根据字段查找索引
found = index_mgr.find_index_by_fields(["age", "name"])

if found:
    print(f"找到索引: {found['name']}")
else:
    print("未找到匹配的索引")

删除索引

index_mgr.delete_index(
    ddoc="_design/xyz",
    name="idx_age"
)

5. 视图管理

ViewManager

管理 CouchDB 视图的完整工具。

创建视图

view_mgr = client.view_manager

# Map 函数
map_func = """
function(doc) {
    if (doc.type === 'users' && doc.age) {
        emit(doc.age, 1);
    }
}
"""

# 创建视图
view_mgr.create_view(
    design_doc="analytics",
    view_name="users_by_age",
    map_function=map_func,
    reduce_function="_count"  # 内置 reduce 函数
)

查询视图

# 查询视图
result = view_mgr.query_view(
    design_doc="analytics",
    view_name="users_by_age",
    start_key=25,           # 起始键
    end_key=35,             # 结束键
    group=True,             # 分组
    reduce=True,            # 执行 reduce
)

# 处理结果
for row in result['rows']:
    print(f"年龄 {row['key']}: {row['value']} 人")

高级查询选项

result = view_mgr.query_view(
    design_doc="analytics",
    view_name="users_by_age",
    key=30,                 # 精确键匹配
    limit=10,               # 限制结果数量
    descending=True,        # 降序
    include_docs=True,      # 包含完整文档
)

删除视图

view_mgr.delete_view(
    design_doc="analytics",
    view_name="users_by_age"
)

6. 性能优化建议

1. 使用查询缓存

# 对于频繁查询的数据
client = SyncCouchDBClient(
    ...,
    enable_cache=True,
    cache_size=200,      # 根据查询类型调整
    cache_ttl=600.0,     # 10分钟
)

2. 批量操作

from sqlalchemy import insert

# 批量插入(使用 _bulk_docs)
stmt = insert(users).values([
    {"name": "User1", "age": 25},
    {"name": "User2", "age": 30},
    # ... 更多记录
])

conn.execute(stmt)  # 自动使用批量插入

3. 创建合适的索引

# 为常用查询创建索引
index_mgr.create_index(
    fields=["created_at"],     # 时间字段
    name="idx_created_at"
)

index_mgr.create_index(
    fields=["status", "priority"],  # 复合索引
    name="idx_status_priority"
)

4. 使用视图进行复杂聚合

对于大数据集的聚合查询,视图比客户端聚合快得多:

# 不推荐:客户端聚合(慢)
results = client.find({"type": "orders"})  # 可能有数百万条
total = QueryProcessor.sum(results, "amount")

# 推荐:使用视图(快)
view_mgr.create_view(
    "stats",
    "total_sales",
    "function(doc) { if (doc.type === 'orders') emit(null, doc.amount); }",
    "_sum"
)

result = view_mgr.query_view("stats", "total_sales")
total = result['rows'][0]['value']

5. 合理设置连接池

client = SyncCouchDBClient(...)
client_obj = client.connect()  # httpx.Client

# 连接池已自动配置:
# - max_connections=100
# - max_keepalive_connections=20
# - connect_timeout=5s
# - read_timeout=30s

📊 性能对比

操作 无优化 有优化 提升
批量插入(100条) ~3秒 ~0.5秒 6x
重复查询 ~200ms ~5ms (缓存) 40x
聚合查询(1万条) ~2秒 ~100ms (视图) 20x
复杂查询 ~500ms ~100ms (索引) 5x

🔍 完整示例

参见 examples/advanced_features.py,包含所有功能的完整演示:

cd examples
python advanced_features.py

📝 注意事项

  1. 缓存一致性: 缓存会在 INSERT/UPDATE/DELETE 后自动失效,但如果有多个客户端修改数据,需要手动失效
  2. 聚合性能: 小数据集(<1000条)用客户端聚合,大数据集用视图
  3. 索引开销: 索引会增加写入开销,只为常用查询创建索引
  4. 重试策略: 根据网络环境调整重试次数和延迟

相关文档: - README.md - 项目概览 - 核心功能(见首页) - 核心功能 - TODO.md - 待办事项

最后更新: 2025-11-03 文档版本: 1.0