本指南将帮助你配置免费的PostgreSQL数据库,解决Render等云平台的数据持久化问题。
在Render、Heroku等云平台部署时,使用JSON文件存储数据会遇到以下问题:
- ❌ 服务重启后数据丢失 - 容器文件系统是临时的
- ❌ 每次部署都需要重新注册 - 用户账号无法保存
- ❌ 打卡记录无法持久化 - 所有历史记录会被清空
使用数据库可以解决这些问题:
- ✅ 数据永久保存 - 独立于应用容器
- ✅ 支持更多用户 - 更好的并发性能
- ✅ 完全免费 - 使用免费数据库服务
Supabase 是最推荐的免费PostgreSQL数据库服务。
- ✅ 永久免费 - 500MB存储空间
- ✅ 无需信用卡 - 注册即可使用
- ✅ 自动备份 - 数据安全有保障
- ✅ 全球CDN - 访问速度快
访问 https://supabase.com 并注册账号(可使用GitHub登录)
- 点击 "New Project"
- 填写项目信息:
- Name:
punch-timer(或任意名称) - Database Password: 设置一个强密码(请记住!)
- Region: 选择离你最近的区域(如
Northeast Asia (Tokyo))
- Name:
- 点击 "Create new project"
- 等待1-2分钟项目创建完成
- 在项目页面,点击左侧菜单的 "Project Settings" (齿轮图标)
- 点击 "Database" 标签
- 找到 "Connection string" 部分
- 选择 "URI" 模式
- 复制连接字符串,格式类似:
postgresql://postgres.xxxxx:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres - 将
[YOUR-PASSWORD]替换为你在步骤2中设置的密码
- 在Supabase项目页面,点击左侧菜单的 "SQL Editor"
- 点击 "New query"
- 复制以下SQL代码并执行:
-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建打卡记录表
CREATE TABLE IF NOT EXISTS punches (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
punch_date DATE NOT NULL,
punch_time TIMESTAMP NOT NULL,
is_late_shift BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, punch_time),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- 创建索引以提高查询性能
CREATE INDEX IF NOT EXISTS idx_punches_user_date ON punches(user_id, punch_date);- 点击 "Run" 执行SQL
- 确认显示 "Success. No rows returned"
- 登录 Render Dashboard
- 选择你的Web Service
- 点击 "Environment" 标签
- 添加环境变量:
- Key:
DATABASE_URL - Value: 粘贴步骤3中获取的连接字符串
- Key:
- 点击 "Save Changes"
- Render会自动重新部署应用
- 等待Render部署完成
- 访问你的应用URL
- 注册一个新账号
- 在Render Dashboard中点击 "Manual Deploy" → "Clear build cache & deploy" 重新部署
- 重新访问应用,使用刚才注册的账号登录
- 如果能成功登录,说明数据库配置成功! 🎉
- 免费额度: 20MB存储
- 注册: https://www.elephantsql.com
- 优点: 简单易用,无需信用卡
- 缺点: 存储空间较小
配置步骤:
- 注册并创建新实例(选择 Tiny Turtle 免费套餐)
- 复制 URL 连接字符串
- 在Render中设置
DATABASE_URL环境变量
- 免费额度: 90天后过期
- 注册: 在Render Dashboard中创建
- 优点: 与Web Service在同一平台
- 缺点: 90天后需要付费或迁移
配置步骤:
- 在Render Dashboard点击 "New +" → "PostgreSQL"
- 选择 Free 套餐
- 创建后复制 Internal Database URL
- 在Web Service中设置
DATABASE_URL环境变量
- 免费额度: $5/月额度
- 注册: https://railway.app
- 优点: 慷慨的免费额度
- 缺点: 需要验证GitHub账号
无需安装PostgreSQL,应用会自动使用SQLite:
# 不设置DATABASE_URL环境变量,或设置为:
DATABASE_URL=sqlite:///punch_timer.db如果你想在本地使用PostgreSQL:
- 安装PostgreSQL
- 创建数据库:
createdb punch_timer
- 设置环境变量:
DATABASE_URL=postgresql://localhost/punch_timer
如果你已经有JSON文件中的数据,可以迁移到数据库:
- 确保
users.json和punches.json文件存在 - 配置好
DATABASE_URL环境变量 - 运行迁移脚本:
python migrate_to_db.py
- 查看迁移日志,确认数据已成功导入
- 备份原JSON文件:
mkdir backup move users.json backup/ move punches.json backup/
migrate_to_db.py 会:
- 读取
users.json中的所有用户 - 读取
punches.json中的所有打卡记录 - 将数据导入到PostgreSQL数据库
- 自动处理重复数据(跳过已存在的记录)
Supabase:
- 在项目页面点击 "Table Editor"
- 选择
users或punches表查看数据
其他数据库: 使用数据库客户端工具如 DBeaver 或 pgAdmin
检查以下几点:
DATABASE_URL格式是否正确- 数据库密码是否包含特殊字符(需要URL编码)
- 网络是否可以访问数据库服务器
- 查看应用日志获取详细错误信息
Supabase:
- 自动每日备份(免费套餐保留7天)
- 手动备份: SQL Editor → 导出数据
手动备份:
# 导出数据
pg_dump $DATABASE_URL > backup.sql
# 恢复数据
psql $DATABASE_URL < backup.sql- Supabase: 500MB对于打卡应用来说非常充足,几乎不可能用完
- ElephantSQL: 如果20MB不够,可以升级或迁移到Supabase
- Render PostgreSQL: 90天后迁移到Supabase
- 在新数据库中执行表创建SQL
- 更新
DATABASE_URL环境变量 - 运行迁移脚本导入数据(如果需要)
- 重新部署应用
可以!应用会根据 DATABASE_URL 自动选择:
- 本地:
DATABASE_URL=sqlite:///punch_timer.db - 生产:
DATABASE_URL=postgresql://...(在Render中设置)
- ✅ 选择数据库服务(推荐Supabase)
- ✅ 按照上述步骤配置数据库
- ✅ 在Render中设置环境变量
- ✅ 部署并测试应用
- ✅ (可选)迁移现有JSON数据
需要帮助? 查看 Supabase文档 或 Render文档