You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,
}

错误截图

SQLITE_ERROR: no such table: dms 报错截图

故障原因

Sequelize的define方法仅用于注册模型结构,不会自动在数据库中创建对应的数据表。当前代码中只完成了Sequelize实例初始化、dms表模型定义和导出操作,从未调用同步方法将模型结构实际写入SQLite数据库文件。
直接执行node database.js也无法解决问题,因为该文件中没有任何执行数据库同步的逻辑,运行后只会完成模块定义就直接退出,不会对数据库文件做任何修改。
另外当前代码的catch块将所有错误统一归类为私信权限关闭,也会误导问题排查方向——本次报错和DM权限无关,是DirectMessages.create操作因为表不存在抛出错误,被catch块捕获后返回了错误的提示信息。

修复步骤
  1. 添加数据库同步逻辑,二选一即可:
    • 方式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 })
      
  2. 优化错误捕获逻辑,区分不同错误类型,避免误导排查:
    将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 })
    }
    
  3. 重启机器人,首次启动时Sequelize会自动检测表是否存在,不存在则自动创建dms表,之后执行/dm指令即可正常写入数据,不会再出现找不到表的报错。

内容的提问来源于stack exchange,提问作者SpeedoThreeSixty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:00:55