MySQL 使用 Typescript 不存储多个数据 - discord.js
MySQL with Typescript doesn't store multiple data - discord.js
- 查询
我正在使用 typescript 和 discord.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 不支持复合主键和外键。您需要将自动生成的唯一主键添加为单个列。如果您希望使用 user
和 guild
列值更新某个记录,那么您需要在它们上添加一个唯一索引(至少它在 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
- 查询
我正在使用 typescript 和 discord.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 不支持复合主键和外键。您需要将自动生成的唯一主键添加为单个列。如果您希望使用 user
和 guild
列值更新某个记录,那么您需要在它们上添加一个唯一索引(至少它在 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