MySQL 使用 Typescript 不存储多个数据 - discord.js

MySQL with Typescript doesn't store multiple data - discord.js

我正在使用 typescriptdiscord.js 开发消息跟踪 discord 机器人。我在下面提供了我的代码。这里的问题是它不保存数据。当一个用户发送消息时,它存储他的消息计数,但当另一个用户在同一频道发送消息时,数据库存储他的消息,并使第一个用户的计数为0

// user-Schema.ts
import type { SapphireClient } from '@sapphire/framework';
import type { ModelStatic, Model } from 'sequelize';
import Sequelize from 'sequelize';

interface UserAttributes {
    guild: string;
    user: string;
    msgs: number;
}

interface UserInstance extends Model<UserAttributes, UserAttributes>, UserAttributes {}

export class UserModel {
    client: SapphireClient;
    raw!: ModelStatic<UserInstance>;

    constructor(client: SapphireClient) {
        this.client = client;
    }

    async init() {
        const db = this.client.sql.define<UserInstance>('electra.users', {
            guild: {
                type: Sequelize.STRING,
                primaryKey: true,
                unique: true
            },
            user: {
                type: Sequelize.STRING,
                primaryKey: true
            },
            msgs: {
                type: Sequelize.INTEGER
            }
        });
        this.raw = db;
        await this.raw.sync();
        this.client.logger.info(`Synced UserModel`);
    }
}
// messageCreate.ts
const data = await this.container.client.userDB.raw.findOne({
            where: {
                guild: msg.guildId,
                user: msg.author.id
            }
        });

const msgs = data === null ? 0 : data.msgs;

await this.container.client.userDB.raw.upsert({
    guild: msg.guildId as string,
    user: msg.author.id,
    msgs: msgs + 1
});
// index.ts
import { UserModel } from './models/user-Schema';
const sequelize = new sql.Sequelize(process.env.DB_NAME!, process.env.DB_USER!, process.env.DB_PASS!, {
    logging: false,
    dialect: 'mysql'
});

client.sql = sequelize;
client.userDB = new UserModel(client);
// ready.ts
await this.container.client.userDB.init()

我正在使用 @sapphire/framework 作为我的机器人框架。我很乐意提供任何形式的帮助,如果有人问我,我愿意提供更多信息。

谢谢。

Sequelize 不支持复合主键和外键。您需要将自动生成的唯一主键添加为单个列。如果您希望使用 userguild 列值更新某个记录,那么您需要在它们上添加一个唯一索引(至少它在 PostgreSQL 中受支持,您需要检查它是否受支持MySQL 还有)。

  • 好吧,我基本上找到了一个简单易用的修复方法。更新后的代码如下:
const db = this.client.sql.define<UserInstance>('electra.users', {
            guild: {
                type: Sequelize.STRING,
                primaryKey: true,
                unique: false
            },
            user: {
                type: Sequelize.STRING,
                primaryKey: true,
                unique: false
            },
            msgs: {
                type: Sequelize.INTEGER,
                unique: false,
                allowNull: false,
                primaryKey: false
            }
        });
        this.raw = db;
        await this.raw.sync();
        this.client.logger.info(`Synced UserModel`);
  • 是时候解释这些变化了,unique 对于那些会不断变化的值来说必须是 false。由于机器人是 multi-guild,因此会有多个公会实例,并且对于它们中的每一个 - 将会有很多用户实例,并且对于这些用户中的每一个 - 他们的消息。因此,所有这些都必须 而不是 是唯一的。

  • 这有点 off-topic 但如果您对模型实例进行了任何更改,我强烈建议大家 删除 您的表。这将应用新更改并且不会导致错误。

随时回答或post一些关于此的信息:D