一、项目简介
在日常开发、测试和数据分析工作中,我们经常需要快速查看 SQLite 数据库中的表结构和数据,也需要保存一些常用 SQL 查询。本文实现一个“基于 Python 的数据库管理工具”全栈项目:用户登录后可以维护数据库连接、保存 SQL 查询模板、执行只读查询,并在仪表盘中查看连接数、模板数和审计日志数量。
项目不是单纯讲数据库概念,而是一个可运行的 Web 全栈应用,包含完整的后端 API、SQLite 数据模型、JWT 登录认证,以及 Vue 3 前端页面。
二、技术栈
- 后端:FastAPI、SQLAlchemy、Pydantic、Uvicorn
- 数据库:SQLite
- 认证:Passlib bcrypt 密码哈希、JWT Bearer Token
- 前端:Vue 3、Vite、Fetch API
- 项目结构:前后端分离,RESTful API 通信
三、系统架构
浏览器 Vue 3 页面
│
│ HTTP + JSON + Bearer Token
▼
FastAPI REST API
│
├── 用户认证模块:注册、登录、当前用户
├── 连接管理模块:新增/查询/更新/删除数据库连接
├── SQL 模板模块:保存/查询/删除常用 SQL
├── 查询执行模块:执行 SELECT/PRAGMA/EXPLAIN
└── 审计统计模块:记录关键操作并展示统计
│
▼
SQLite:系统业务库 db_manager.db + 示例数据 demo_data.db
其中 db_manager.db 保存用户、数据库连接、SQL 模板和审计记录;demo_data.db 是系统启动时自动创建的示例业务库,用于快速测试查询功能。
四、功能模块
- 用户模块
- 用户注册
- 用户登录
- 密码 bcrypt 哈希
- JWT token 鉴权
- 数据库连接模块
- 创建 SQLite 连接
- 查看当前用户的连接列表
- 修改连接信息
- 删除连接
- SQL 查询模块
- 执行只读 SQL
- 返回列名、行数据和行数
- 保存常用 SQL 模板
- 删除 SQL 模板
- 前端页面模块
- 登录/注册切换
- 登录状态保持
- 数据库连接表单
- SQL 查询台
- 查询结果表格
- 退出登录
- 审计统计模块
- 创建连接、删除连接、执行 SQL 等操作写入审计日志
- 仪表盘展示连接数、模板数、审计记录数
五、数据库/数据模型设计
后端使用 SQLAlchemy 定义 ORM 模型,核心表如下:
| 表名 | 说明 | 关键字段 |
|---|---|---|
| users | 系统用户 | username、email、hashed_password |
| db_connections | 数据库连接 | name、db_type、database_path、owner_id |
| saved_queries | SQL 模板 | title、sql_text、connection_id、owner_id |
| audit_logs | 操作审计 | action、detail、owner_id、created_at |
backend/app/models.py 中的用户模型示例:
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String(50), unique=True, index=True, nullable=False)
email = Column(String(120), unique=True, index=True, nullable=False)
hashed_password = Column(String(255), nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
数据库连接表和 SQL 模板表都通过 owner_id 关联到用户,保证用户只能访问自己的资源。
六、后端接口设计
| 方法 | 地址 | 说明 | 是否鉴权 |
|---|---|---|---|
| POST | /auth/register |
注册用户 | 否 |
| POST | /auth/login |
登录并获取 token | 否 |
| GET | /users/me |
获取当前用户 | 是 |
| GET | /dashboard |
获取统计数据 | 是 |
| POST | /connections |
新增数据库连接 | 是 |
| GET | /connections |
查询数据库连接列表 | 是 |
| PUT | /connections/{id} |
修改数据库连接 | 是 |
| DELETE | /connections/{id} |
删除数据库连接 | 是 |
| POST | /queries |
保存 SQL 模板 | 是 |
| GET | /queries |
查询 SQL 模板列表 | 是 |
| DELETE | /queries/{id} |
删除 SQL 模板 | 是 |
| POST | /execute |
执行只读 SQL | 是 |
登录接口使用 OAuth2 表单格式,返回结果如下:
{
"access_token": "eyJ...",
"token_type": "bearer"
}
前端后续请求会在请求头中携带:
Authorization: Bearer <access_token>
七、前端页面设计
前端采用 Vue 3 + Vite 构建单页应用,主要页面区域如下:
- 登录/注册卡片:未登录时展示,注册成功后提示用户登录。
- 顶部栏:展示系统名称和退出按钮。
- 仪表盘卡片:展示连接数、SQL 模板数和审计日志数量。
- 数据库连接管理:新增连接、展示连接列表、删除连接。
- SQL 查询台:选择连接、输入 SQL、执行查询、保存模板。
- 查询结果表格:根据后端返回的 columns 和 rows 动态渲染。
- SQL 模板列表:可复用或删除已保存模板。
API 封装位于 frontend/src/api.js,统一处理后端地址、token 和错误响应。
八、核心代码讲解
1. 数据库连接配置
backend/app/database.py 使用 SQLAlchemy 创建业务数据库连接:
SQLALCHEMY_DATABASE_URL = "sqlite:///./db_manager.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
connect_args={"check_same_thread": False},
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
get_db() 作为 FastAPI 依赖注入函数,确保每次请求结束后关闭数据库会话。
2. 密码哈希与 JWT
backend/app/crud.py 中封装认证逻辑:
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def get_password_hash(password: str) -> str:
return pwd_context.hash(password)
def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
登录成功后创建 JWT:
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
to_encode = data.copy()
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
3. 接口鉴权
backend/app/main.py 通过 OAuth2PasswordBearer 获取 token,再解析当前用户:
def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
username = crud.decode_token(token)
if not username:
raise HTTPException(status_code=401, detail="无效或过期的登录凭证")
user = crud.get_user_by_username(db, username)
if not user:
raise HTTPException(status_code=401, detail="用户不存在")
return user
只要接口参数中加入 current_user: models.User = Depends(get_current_user),就会自动启用登录保护。
4. 只读 SQL 执行
为了避免演示系统误删数据,执行 SQL 时只允许 SELECT、PRAGMA、EXPLAIN:
sql = request.sql_text.strip()
first_word = sql.split(None, 1)[0].lower() if sql else ""
if first_word not in {"select", "pragma", "explain"}:
raise ValueError("演示系统仅允许 SELECT/PRAGMA/EXPLAIN 只读语句")
查询结果使用 sqlite3.Row 转换为字典列表,方便前端渲染动态表格。
5. 前端登录状态处理
frontend/src/api.js 将 token 保存到 localStorage,并在请求时自动携带:
export function getToken() {
return localStorage.getItem('db_manager_token')
}
async function request(path, options = {}) {
const headers = options.headers || {}
const token = getToken()
if (token) headers.Authorization = `Bearer ${token}`
const response = await fetch(`${API_BASE}${path}`, { ...options, headers })
const data = await response.json().catch(() => ({}))
if (!response.ok) throw new Error(data.detail || '请求失败')
return data
}
App.vue 在页面加载时检查 token,如果有效则自动进入系统;退出登录则清除 token。
九、部署与运行步骤
1. 启动后端
cd project/backend python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
后端默认地址:http://127.0.0.1:8000,接口文档:http://127.0.0.1:8000/docs。
2. 启动前端
cd project/frontend npm install npm run dev
前端 Vite 开发服务通常运行在:http://127.0.0.1:5173。
3. 初始化与使用示例
- 打开前端页面并注册账号。
- 登录成功后创建数据库连接。
- SQLite 路径填写:
./demo_data.db。 - 在查询台输入:
SELECT * FROM employees;
- 点击“执行只读查询”,即可看到示例员工数据。
- 点击“保存为模板”,可以把常用 SQL 保存在个人模板列表中。
十、项目总结
本文完成了一个完整的 Python 数据库管理工具全栈项目。后端通过 FastAPI 提供 RESTful API,SQLite 保存业务数据,Passlib 和 JWT 实现了注册、登录与接口鉴权;前端通过 Vue 3 + Vite 实现了登录注册、连接管理、SQL 查询台和结果展示。
这个项目可以继续扩展:例如支持更多数据库类型、增加表结构浏览器、支持分页查询、增加 SQL 收藏分类、引入角色权限控制、增加审计日志检索等。对于想学习 Python 全栈开发的同学来说,它覆盖了从认证、数据库模型、接口设计到前端状态管理的关键知识点。













