Sequelize.define()定义模型后SQLite未自动创建表问题排查
问题描述
- 代码仓库地址:spelta-discord-bot 开发分支
- 场景:基于Discord.js开发Discord机器人,计划新增
dm、reply、followup三个私信相关指令,选用SQLite作为存储数据库实现回复最新私信的功能,参考Sequelize相关文档编写了database.js配置文件,但运行dm指令时发现对应数据表未创建。 - 已尝试操作:代码编辑器可正常识别
database.js与生成的database.sqlite文件,直接执行node database.js命令后问题仍未解决。 - 故障现象:实际运行时主账号和测试小号可正常收到Discord私信,但交互会触发catch逻辑返回*"Error! Either you or the recipient have disabled DMs!"*错误提示,后台报错为
SQLITE_ERROR: no such table: dms。
相关代码
commands/dm.js
const { SlashCommandBuilder } = require("@discordjs/builders") const { DirectMessages } = require("../database") module.exports = { data: new SlashCommandBuilder() .setName("dm") .setDescription("Directly messages a user!") .addUserOption(option => option .setRequired(true) .setName("user") .setDescription("The user to message")) .addStringOption(option => option .setRequired(true) .setName("message") .setDescription("The message to send")), async execute(interaction) { const user = interaction.options.getUser("user") const message = interaction.options.getString("message") try { await user.send(`**${interaction.user.tag} sent a message:** ${message}`) await interaction.user.send(`**Sent ${user.tag} a message:** ${message}`) await DirectMessages.create({ message, from: interaction.user.id, to: user.id, }) interaction.reply({ content: "Successfully sent your message!", ephemeral: true }) } catch (error) { console.error(error) interaction.reply({ content: "Error! Either the recipient or yourself has disabled DMs!", ephemeral: true }) } }, }
database.js
const Sequelize = require("sequelize") const sequelize = new Sequelize("database", "user", "password", { host: "localhost", dialect: "sqlite", logging: false, // SQLite only storage: "database.sqlite", }) const DirectMessages = sequelize.define("dms", { message: Sequelize.TEXT, from: Sequelize.STRING, to: Sequelize.STRING, }) module.exports = { sequelize, DirectMessages, }
错误截图

故障原因
Sequelize的define方法仅用于注册模型结构,不会自动在数据库中创建对应的数据表。当前代码中只完成了Sequelize实例初始化、dms表模型定义和导出操作,从未调用同步方法将模型结构实际写入SQLite数据库文件。
直接执行node database.js也无法解决问题,因为该文件中没有任何执行数据库同步的逻辑,运行后只会完成模块定义就直接退出,不会对数据库文件做任何修改。
另外当前代码的catch块将所有错误统一归类为私信权限关闭,也会误导问题排查方向——本次报错和DM权限无关,是DirectMessages.create操作因为表不存在抛出错误,被catch块捕获后返回了错误的提示信息。
修复步骤
- 添加数据库同步逻辑,二选一即可:
- 方式1:直接在
database.js末尾添加同步代码,添加后执行一次node database.js即可完成建表:// 放在module.exports之前即可,force设为false避免已存在的表被删除丢失数据 sequelize.sync({ force: false }) .then(() => console.log("数据库表同步完成")) .catch(err => console.error("数据库同步失败:", err)) - 方式2(推荐):在机器人入口文件(通常为
index.js/bot.js)中,机器人登录Discord前执行同步,不需要单独运行database.js:// 入口文件顶部导入部分添加 const { sequelize } = require("./database") // 放在client.login(TOKEN)之前执行 await sequelize.sync({ force: false })
- 方式1:直接在
- 优化错误捕获逻辑,区分不同错误类型,避免误导排查:
将dm.js中的catch块修改为:catch (error) { console.error(error) let replyMsg = "操作失败:" // 50007是Discord API返回的无法向用户发送私信的专属错误码 if (error.code === 50007) { replyMsg += "你或消息接收方已关闭私信权限,无法发送消息" } else { replyMsg += `内部错误:${error.message}` } interaction.reply({ content: replyMsg, ephemeral: true }) } - 重启机器人,首次启动时Sequelize会自动检测表是否存在,不存在则自动创建
dms表,之后执行/dm指令即可正常写入数据,不会再出现找不到表的报错。
内容的提问来源于stack exchange,提问作者SpeedoThreeSixty
相关产品推荐
相关产品推荐

