三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

ExtendDB 实战:用 DynamoDB API 操作本地 SQLite,开发测试不再连线上

ExtendDB 实战:用 DynamoDB API 操作本地 SQLite,开发测试不再连线上

每次本地开发要用 DynamoDB,你有几个选择:

  1. 连线上 DynamoDB(费钱 + 可能误操作生产表)
  2. 用 DynamoDB Local(Java 的,启动慢,行为和线上有差异)
  3. 自己 Mock(维护成本高,覆盖不全)

现在多了第四个选择——ExtendDB,亚马逊云科技官方开源的 DynamoDB 兼容适配器。

它提供完整的 DynamoDB API 兼容层,底层存储可以自定义。本地开发时指向 ExtendDB,线上环境指向真正的 DynamoDB,代码零修改。

ExtendDB 是什么

一句话:让你用 DynamoDB API 操作非 DynamoDB 后端

具体来说:

  • 实现了 DynamoDB 的 API 协议(CreateTable、PutItem、GetItem、Query、Scan、BatchWrite 等)
  • 底层存储可插拔(SQLite、PostgreSQL、文件系统等)
  • 完全兼容 AWS SDK——你的 boto3/aws-sdk-js 代码不需要任何修改

为什么这东西有用

场景一:本地开发

import boto3# 本地开发 → 连 ExtendDB
# 生产环境 → 连真正的 DynamoDB
# 代码完全一样,只改 endpointif os.environ.get('ENV') == 'local':dynamodb = boto3.resource('dynamodb',endpoint_url='http://localhost:8787',  # ExtendDBregion_name='us-east-1',aws_access_key_id='local',aws_secret_access_key='local')
else:dynamodb = boto3.resource('dynamodb')# 之后的代码完全一样
table = dynamodb.Table('users')
table.put_item(Item={'user_id': 'u-001','name': '张三','email': 'zhangsan@example.com','created_at': '2026-05-27T12:00:00Z'
})response = table.get_item(Key={'user_id': 'u-001'})
print(response['Item'])

场景二:CI/CD 测试

# GitHub Actions 里用 ExtendDB 替代 DynamoDB Local
name: Test
on: [push]
jobs:test:runs-on: ubuntu-latestservices:extenddb:image: aws/extenddb:latestports:- 8787:8787steps:- uses: actions/checkout@v4- name: Run testsenv:DYNAMODB_ENDPOINT: http://localhost:8787run: |npm installnpm test

比 DynamoDB Local 轻量得多——不需要 Java 运行时,启动秒级。

场景三:跨后端迁移评估

想把部分数据从 DynamoDB 迁到其他存储但不确定影响?可以先用 ExtendDB 对接目标后端跑测试,确认兼容性后再做正式迁移。

快速上手

Docker 启动

# 拉取镜像
docker pull aws/extenddb:latest# 启动(默认 SQLite 后端)
docker run -d \--name extenddb \-p 8787:8787 \-v extenddb-data:/data \aws/extenddb:latest# 验证
aws dynamodb list-tables \--endpoint-url http://localhost:8787 \--region us-east-1

源码编译

# 克隆仓库
git clone https://github.com/aws/extenddb.git
cd extenddb# 编译(Go 项目)
go build -o extenddb ./cmd/extenddb# 启动
./extenddb --port 8787 --backend sqlite --data-dir ./data

配置后端

# extenddb.yaml
server:port: 8787host: 0.0.0.0backend:type: sqlite  # 可选: sqlite, postgres, memorysqlite:path: /data/extenddb.db# postgres:#   host: localhost#   port: 5432#   database: extenddb#   user: admin#   password: ${DB_PASSWORD}logging:level: infoformat: json

API 兼容性

ExtendDB 支持的 DynamoDB API 操作:

操作 状态 备注
CreateTable 含 GSI/LSI
DeleteTable
DescribeTable
PutItem 含条件表达式
GetItem 含投影表达式
UpdateItem 含更新表达式
DeleteItem 含条件表达式
Query 含 KeyCondition + Filter
Scan 含过滤和分页
BatchWriteItem
BatchGetItem
TransactWriteItems
TransactGetItems

不支持的(或部分支持):

  • DynamoDB Streams(暂不支持)
  • TTL 自动删除(计划中)
  • 全局表(不适用于本地场景)

和 DynamoDB Local 对比

对比项 DynamoDB Local ExtendDB
运行时 Java(JVM) Go(原生二进制)
启动时间 几秒~十几秒 毫秒级
内存占用 200MB+ 20-50MB
Docker 镜像 ~500MB ~30MB
持久化 SharedDb 模式 多后端可选
API 兼容度 高(官方维护) 高(社区验证中)
开源 是(Apache 2.0)
数据可见性 黑盒 SQLite/PG 可直接查

ExtendDB 最大的优势:轻量 + 开源 + 数据可见。

用 SQLite 后端时,你可以直接用 sqlite3 打开数据文件看里面存了什么,debug 超级方便。DynamoDB Local 做不到这点。

在项目中集成

Node.js + Jest 测试

// test/setup.js
const { DynamoDBClient, CreateTableCommand } = require('@aws-sdk/client-dynamodb');const client = new DynamoDBClient({endpoint: process.env.DYNAMODB_ENDPOINT || 'http://localhost:8787',region: 'us-east-1',credentials: { accessKeyId: 'local', secretAccessKey: 'local' }
});beforeAll(async () => {await client.send(new CreateTableCommand({TableName: 'test-users',KeySchema: [{ AttributeName: 'pk', KeyType: 'HASH' }],AttributeDefinitions: [{ AttributeName: 'pk', AttributeType: 'S' }],BillingMode: 'PAY_PER_REQUEST'}));
});afterAll(async () => {// ExtendDB 支持 DeleteTable 清理
});

Python + pytest

# conftest.py
import pytest
import boto3
import os@pytest.fixture(scope='session')
def dynamodb():endpoint = os.environ.get('DYNAMODB_ENDPOINT', 'http://localhost:8787')resource = boto3.resource('dynamodb',endpoint_url=endpoint,region_name='us-east-1',aws_access_key_id='local',aws_secret_access_key='local')# 创建测试表table = resource.create_table(TableName='test-orders',KeySchema=[{'AttributeName': 'order_id', 'KeyType': 'HASH'},{'AttributeName': 'created_at', 'KeyType': 'RANGE'}],AttributeDefinitions=[{'AttributeName': 'order_id', 'AttributeType': 'S'},{'AttributeName': 'created_at', 'AttributeType': 'S'}],BillingMode='PAY_PER_REQUEST')table.wait_until_exists()yield resourcedef test_create_order(dynamodb):table = dynamodb.Table('test-orders')table.put_item(Item={'order_id': 'ord-001','created_at': '2026-05-27T10:00:00Z','amount': 99.9,'status': 'pending'})resp = table.get_item(Key={'order_id': 'ord-001','created_at': '2026-05-27T10:00:00Z'})assert resp['Item']['amount'] == 99.9

我的判断

ExtendDB 填补了 DynamoDB 开发体验中的一个老缺口。

DynamoDB 的线上体验很好(零运维、自动扩缩),但本地开发体验一直是短板。DynamoDB Local 太重(Java)、启动慢、不开源。很多团队因为这个原因在本地开发时用别的数据库(Redis、PostgreSQL),但这就带来了本地和线上行为不一致的问题。

ExtendDB 的思路很务实:Go 原生二进制、启动快、开源、数据可见。对于日常开发和 CI 测试来说,这比 DynamoDB Local 好用。

不过要注意:它还在早期阶段,生产环境不要用它替代真正的 DynamoDB。它是开发/测试工具,不是生产存储。


相关链接:

  • ExtendDB 公告:https://aws.amazon.com/about-aws/whats-new/2026/05/aws-extenddb-dynamodb/
  • GitHub 仓库:https://github.com/aws/extenddb
  • DynamoDB 产品页:https://aws.amazon.com/dynamodb/
  • DynamoDB 开发者指南:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/
← 返回列表