本文详解 Telethon 在 Ubuntu 服务器上因会话路径配置不当导致 sqlite3.OperationalError: unable to open database file 的根本原因,并提供可立即生效的修复方案,涵盖路径规范、权限适配与健壮性增强实践。
本文详解 telethon 在 ubuntu 服务器上因会话路径配置不当导致 `sqlite3.operationalerror: unable to open database file` 的根本原因,并提供可立即生效的修复方案,涵盖路径规范、权限适配与健壮性增强实践。
Telethon 默认使用 SQLite 存储会话数据(如授权状态、密钥、对话缓存等),其会话参数(session_name)不仅决定会话标识,更直接作为 SQLite 数据库文件的
相对或绝对路径
。在你的代码中:
Telethon 将尝试在当前工作目录下创建并访问 sessions/Bot.session 文件(注意:.session 后缀由 Telethon 自动添加)。但问题在于:
sessions/ 目录并不存在
—— 即使 database.db 和 config.ini 能被读取,TelegramClient 初始化时会立即尝试连接该路径下的 SQLite 文件,而 Python 的 sqlite3.connect() 在父目录不存在时将直接抛出 OperationalError: unable to open database file,且不提供更明确的“目录不存在”提示。
这正是本地开发环境与 Ubuntu 服务器行为差异的根源:
本地运行时,你可能在项目根目录执行 python script.py,当前工作目录即 /path/to/project/,此时 sessions/ 若已存在则无误;
但在服务器上,若以 root 用户通过 systemd、cron 或直接调用 /usr/local/bin/project/script.py 启动,
当前工作目录极大概率是 /root 或 /
,而非 /usr/local/bin/project/ —— 导致 sessions/Bot.session 被解析为 /root/sessions/Bot.session 或 /sessions/Bot.session,而这些路径既无写入权限,也无 sessions 目录。
✅ 正确解决方案(推荐两种方式)
方案一:使用绝对路径 + 自动创建目录(最健壮)
修改 session_name 为基于项目目录的绝对路径,并确保父目录存在:
✅ 优势:完全解耦工作目录,路径明确可控;exist_ok=True 避免重复创建异常。
方案二:简化会话名(快速修复)
若无需自定义会话子目录,直接使用纯文件名:
⚠️ 注意:此方案
仍需确保启动时的工作目录正确
。建议配合 cd /usr/local/bin/project && python script.py 使用,或在脚本开头强制切换:
? 权限与安全补充说明
你提供的文件权限(如 database.db 为 -rw-rw-rw-)虽可读写,但存在安全隐患:
root 用户拥有全部文件,但 Telethon 会话文件含敏感密钥,
不应赋予组/其他用户写权限
;
更佳实践:设为 600(仅所有者读写):
若使用 sessions/ 目录,同样设置:
? 验证与调试技巧
启动前打印实际会话路径,确认是否符合预期:
检查 SQLite 文件是否成功生成:
? 总结
unable to open database file 在 Telethon 中几乎总是路径问题,而非数据库损坏或权限不足(除非目录不可写)。核心原则是:
永远显式管理会话路径,拒绝隐式相对路径依赖
。采用 os.path.abspath(__file__) 定位项目根目录,再构建绝对路径,是跨平台、跨部署场景下最可靠的做法。同时,结合最小权限原则配置文件系统权限,兼顾功能与安全。
至此,你的 Telegram Bot 将在 Ubuntu 服务器上稳定持久化会话,不再因路径歧义中断初始化流程。
session_name = "sessions/Bot"
client = TelegramClient(session_name, API_ID, API_HASH).start(bot_token=BOT_TOKEN)import os
# 获取 script.py 所在目录(推荐:避免依赖当前工作目录)
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
SESSION_PATH = os.path.join(PROJECT_DIR, "sessions", "Bot")
# 确保 sessions 目录存在
os.makedirs(os.path.dirname(SESSION_PATH), exist_ok=True)
client = TelegramClient(SESSION_PATH, API_ID, API_HASH).start(bot_token=BOT_TOKEN)session_name = "Bot" # Telethon 将在当前工作目录创建 Bot.sessionimport os
os.chdir(os.path.dirname(os.path.abspath(__file__)))chmod 600 /usr/local/bin/project/database.db
chmod 600 /usr/local/bin/project/config.inichmod 700 /usr/local/bin/project/sessionsprint(f"Session will be stored at: {SESSION_PATH}.session")ls -la /usr/local/bin/project/sessions/
# 应看到 Bot.session 文件(大小 > 0)