feat(config): add database switch between InMemory and PostgreSQL
Deploy / Deploy Staging (push) Failing after 5s
Deploy / Deploy Production (push) Has been skipped
Tests / test (push) Failing after 18s
Tests / lint (push) Failing after 18s

- Add USE_IN_MEMORY_DB config flag
- Auto-select repository implementation based on config
- InMemory: for development and testing (no setup needed)
- PostgreSQL: for production (persistent data)
- Update DependencyContainer to support both
- Add documentation for switching databases
- Update .env.example with new config

Phase 4 Task 36/68 completed
This commit is contained in:
Xiaoxia AI
2026-06-17 08:25:20 +08:00
parent 8095539dd4
commit 3f3821581c
4 changed files with 244 additions and 3 deletions
+6
View File
@@ -7,6 +7,12 @@ BASE_URL=http://localhost:3000
# ==================== 数据库配置 ====================
DATABASE_URL=postgresql://xiaoxia_user:your_password@localhost:5432/xiaoxia_saas
# 开发环境:使用内存数据库(不需要 PostgreSQL)
USE_IN_MEMORY_DB=true
# 生产环境:使用 PostgreSQL
# USE_IN_MEMORY_DB=false
# ==================== Redis 配置 ====================
REDIS_URL=redis://localhost:6379/0
+1
View File
@@ -16,6 +16,7 @@ class Settings(BaseSettings):
# 数据库配置
DATABASE_URL: str = "postgresql://xiaoxia:password@localhost:5432/xiaoxia_saas"
USE_IN_MEMORY_DB: bool = False # True = 使用内存数据库,False = 使用 PostgreSQL
# Redis 配置
REDIS_URL: str = "redis://localhost:6379/0"
+21 -3
View File
@@ -55,19 +55,37 @@ class DependencyContainer:
@property
def user_repository(self):
if self._user_repository is None:
self._user_repository = InMemoryUserRepository()
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.user_repository import InMemoryUserRepository
self._user_repository = InMemoryUserRepository()
else:
from packages.adapters.postgres.user_repository import PostgresUserRepository
self._user_repository = PostgresUserRepository(settings.DATABASE_URL)
return self._user_repository
@property
def workspace_repository(self):
if self._workspace_repository is None:
self._workspace_repository = InMemoryWorkspaceRepository()
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.workspace_repository import InMemoryWorkspaceRepository
self._workspace_repository = InMemoryWorkspaceRepository()
else:
from packages.adapters.postgres.workspace_repository import PostgresWorkspaceRepository
self._workspace_repository = PostgresWorkspaceRepository(settings.DATABASE_URL)
return self._workspace_repository
@property
def workspace_member_repository(self):
if self._workspace_member_repository is None:
self._workspace_member_repository = InMemoryWorkspaceMemberRepository()
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.workspace_member_repository import InMemoryWorkspaceMemberRepository
self._workspace_member_repository = InMemoryWorkspaceMemberRepository()
else:
from packages.adapters.postgres.workspace_member_repository import PostgresWorkspaceMemberRepository
self._workspace_member_repository = PostgresWorkspaceMemberRepository(settings.DATABASE_URL)
return self._workspace_member_repository
@property
+216
View File
@@ -0,0 +1,216 @@
# 数据库切换指南
## 📚 概述
小虾 SaaS 支持两种数据存储方式:
1. **InMemory(内存数据库)** - 开发和测试环境
2. **PostgreSQL** - 生产环境
通过环境变量 `USE_IN_MEMORY_DB` 控制。
---
## 🔄 快速切换
### 方式 1: 环境变量
在 `.env` 文件中设置:
```env
# 使用内存数据库(开发/测试)
USE_IN_MEMORY_DB=true
# 使用 PostgreSQL(生产)
USE_IN_MEMORY_DB=false
DATABASE_URL=postgresql://user:pass@localhost:5432/xiaoxia_saas
```
### 方式 2: 启动时指定
```bash
# 使用内存数据库
USE_IN_MEMORY_DB=true uvicorn apps.api.main:app --reload
# 使用 PostgreSQL
USE_IN_MEMORY_DB=false uvicorn apps.api.main:app --reload
```
---
## 💡 InMemory 数据库
**特点:**
- ✅ 无需安装 PostgreSQL
- ✅ 无需数据库迁移
- ✅ 快速启动
- ✅ 适合开发和测试
- ❌ 重启后数据丢失
- ❌ 不适合生产环境
**使用场景:**
- 本地开发
- 单元测试
- 集成测试
- 快速原型验证
**启动:**
```bash
# 设置环境变量
export USE_IN_MEMORY_DB=true
# 启动服务
uvicorn apps.api.main:app --reload
```
---
## 🗄️ PostgreSQL 数据库
**特点:**
- ✅ 数据持久化
- ✅ 支持事务
- ✅ 生产就绪
- ✅ 支持并发
- ❌ 需要安装 PostgreSQL
- ❌ 需要运行数据库迁移
**使用场景:**
- 生产环境
- 预发布环境
- 需要数据持久化的场景
**设置步骤:**
1. **安装 PostgreSQL**
```bash
# Ubuntu
sudo apt-get install postgresql
# macOS
brew install postgresql
```
2. **创建数据库**
```bash
sudo -u postgres psql
CREATE DATABASE xiaoxia_saas;
CREATE USER xiaoxia_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE xiaoxia_saas TO xiaoxia_user;
\q
```
3. **运行迁移**
```bash
psql postgresql://xiaoxia_user:password@localhost:5432/xiaoxia_saas \
-f migrations/001_initial_schema.sql
```
4. **配置环境变量**
```env
USE_IN_MEMORY_DB=false
DATABASE_URL=postgresql://xiaoxia_user:password@localhost:5432/xiaoxia_saas
```
5. **启动服务**
```bash
uvicorn apps.api.main:app --reload
```
---
## 🐳 Docker 环境
### docker-compose(自动配置 PostgreSQL)
```bash
# 自动启动 PostgreSQL 和应用
docker-compose up -d
# 查看日志
docker-compose logs -f api
```
`docker-compose.yml` 默认使用 PostgreSQL。
---
## 🧪 测试环境
### 单元测试(推荐 InMemory)
```python
# tests/conftest.py
import os
os.environ['USE_IN_MEMORY_DB'] = 'true'
```
### 集成测试(可选 PostgreSQL)
```bash
# 使用 PostgreSQL 进行集成测试
USE_IN_MEMORY_DB=false pytest tests/integration -v
```
---
## 🔧 实现原理
依赖注入容器根据配置自动选择:
```python
# apps/api/app/dependencies.py
@property
def user_repository(self):
if settings.USE_IN_MEMORY_DB:
return InMemoryUserRepository()
else:
return PostgresUserRepository(settings.DATABASE_URL)
```
**优点:**
- 业务逻辑无需改动
- 切换透明
- 测试隔离
---
## ⚠️ 注意事项
1. **数据不兼容**
- InMemory 和 PostgreSQL 之间无法直接迁移数据
- 切换前请备份重要数据
2. **性能差异**
- InMemory 更快(无 I/O)
- PostgreSQL 支持更大数据量
3. **并发支持**
- InMemory 不支持多进程
- PostgreSQL 支持多进程和集群
4. **环境一致性**
- 开发环境建议使用 InMemory
- 生产环境必须使用 PostgreSQL
---
## 🚀 最佳实践
1. **开发流程**
```
开发(InMemory) → 测试(InMemory) → 预发布(PostgreSQL) → 生产(PostgreSQL)
```
2. **配置管理**
- 使用 `.env` 文件管理配置
- 不要提交 `.env` 到版本控制
- 使用 `.env.example` 作为模板
3. **数据库迁移**
- 所有 schema 变更都要有迁移脚本
- 迁移脚本要幂等(可多次执行)
- 测试迁移脚本后再应用到生产
---
**最后更新:** 2026-06-17