feat(config): add database switch between InMemory and PostgreSQL
- 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:
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user