Discord.js experiences limitations with storing multiple data in conjunction with TypeScript when using MySQL

  • Question

Currently, I am developing a Discord bot to track messages using typescript and discord.js. I have included my code below. The issue I am facing is that the data is not being saved correctly. Each time a user sends messages, their message count is stored. However, if another user sends messages in the same channel, the database replaces the previous user's count with 0.

  • Code Snippet
// 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()
  • Additional Information

I am utilizing @sapphire/framework as the framework for my bot. Any assistance or guidance would be greatly appreciated, and I am willing to provide more details upon request.

Thank you.

Answer №1

Sequelize lacks support for composite primary and foreign keys. To work around this, you'll need to introduce a unique auto-generated primary key as a standalone column. If you plan to perform upsert operations based on the values of the user and guild columns, you must establish a unique index on them (this feature is confirmed in PostgreSQL; verify its availability in MySQL).

Answer №2

  • After some experimentation, I managed to come up with a simple and effective solution. The updated code can be seen below:
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`);
  • Let me break down the changes for you. In this scenario, the unique attribute should be set to false for values that are subject to change. Given that the bot operates in multiple guilds, each guild will have numerous user instances, and each user will have a message count. Therefore, uniqueness is not required for these attributes.

  • On a side note, I recommend dropping your tables if you have modified the model instance. This ensures that the changes are applied correctly without any errors.

Feel free to share your thoughts or provide additional insights on this topic! :D

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with routing in a bundled Angular 2 project using webpack

Having a simple Angular application with two components (AppComponent and tester) webpacked into a single app.bundle.js file, I encountered an issue with routing after bundling. Despite trying various online solutions, the routing feature still does not wo ...

What is the best way to include 2 or more radio buttons in every row of data within a table?

Is it possible to have multiple radio buttons for each row of data in a table? The current code snippet is as follows: echo '<table> <tr> <td>Home</td> <td>Not Home</td> <td>Address</td> <td>Su ...

Changing the fill color of externally imported SVGs from a CDN: A simple guide

While working on a website project using Next JS, I came across the challenge of displaying SVG icons stored in Sanity and dynamically changing their fill color. Is it possible to achieve this feature, such as changing the color when hovering over the icon ...

Implementing Login using Google in a Nativescript iOS application: A step-by-step guide

I've been working on implementing Google's ID provider login in Nativescript using the nativescript-social-login plugin. While it works smoothly on Android, I've hit a roadblock with iOS. Following the instructions from the plugin creator, ...

SQL query for combining two fields from separate tables

I am seeking a solution to generate a report that highlights the various reasons for issues encountered in a job, such as damaged goods or undelivered items. select group_concat(distinct concat( 'sum((select count(jp1.MemReason) from ...

The method of evaluating in-line is distinct from evaluating outside of the

What causes the compiler to produce different results for these two mapped types? type NonNullableObj1<O> = {[Key in keyof O] : O[Key] extends null ? never : O[Key]} type NotNull<T> = T extends null ? never : T; type NonNullableObj2<T> = ...

A versatile generic type infused with dynamic typing and optional parameter flexibility

Looking to develop a function that can accept an optional errorCallback parameter. In cases where the consumer of this function does not provide a callback, I aim to default to a preset handler. The key criteria here are strong typing and utilizing the ret ...

Verifying the presence of a row in the MYSQL database

Recently, I've been facing an issue with checking my database for existing rows. The message "User ID already exists for another Employee" keeps showing up, regardless of whether the row actually exists or not. This problem has really puzzled me, espe ...

How do you manage dependencies for nested components within Angular2?

Encountering an Issue: browser_adapter.js:76 Error: Cannot resolve all parameters for NestedComponent(undefined). Make sure they all have valid type or annotations. at NoAnnotationError.BaseException [as constructor] Diving Deeper Into the Problem: ...

How to implement a dynamic tag using TypeScript in React?

How can I implement dynamic tag typing in React using TypeScript? Take a look at the following code snippet: interface CompProps { tag: string; } const MyComponent: React.FunctionComponent<CompProps> = ({ tag = "div", children }) => { co ...

Establishing a connection between ReactJS and a database

How can I efficiently retrieve data from a one-field form in React JS on the front end and insert it into a MySQL database using Express on the backend? Can you outline the step-by-step process for me? ...

Is it possible to access your app directly from the browser without requiring any user prompts?

After successfully setting up my app for both android and ios with the necessary app link and universal link, I am now focusing on redirecting users from a specific website to my app. The mobile aspect is all set, but I need to work on the browser/server s ...

The Vite proxy server will not modify POST requests

When I set up a proxy using Vite, I noticed that it only handles GET and HEAD requests. I'm looking to have other request methods proxied as well. In a new Vite React project - the only modification I made was in vite.config.ts import { defineConfig ...

Failed to access element from the array using specified id

Seeking assistance with creating dynamic pages for each object in the boxArray file. I've developed a service called boxService to extract objects. While I am able to retrieve all elements successfully, encountering errors when attempting to extract i ...

experiencing difficulties when trying to establish a connection to a MySQL database using PHP

I have encountered an issue while working on my new project. Despite inputting the correct DB name and user name, I am still receiving an error when trying to connect to my database. The error message reads: Fatal error: Uncaught Error: Call to undefined ...

Angular removing every query string parameters

Linked to but distinct from: How to maintain query string parameters in URL when accessing a route of an Angular 2 app? I am facing an issue with my basic Angular application where adding a query parameter results in its removal, both from the browser&apo ...

How can I retrieve the last few rows from multiple tables in MySql?

I've been struggling with an SQL query for the past few hours. I need to retrieve the latest records from four tables: events, contactinfo, video, and news. Specifically, I want the last 3 results from events and news, and the most recent record from ...

Issue encountered when attempting to insert data via node into MySQL database

As a new Node developer, I am in the process of building some initial applications. Currently, I am working on inserting records into a MySQL database using Node. Below is an example of my post method: router.post('/add',function(req,res){ c ...

Setting up Typescript classes that inherit from one another with diverse properties for each subclass

I'm fairly new to Typescript and currently grappling with how to effectively manage class inheritance when base classes have distinct properties. Essentially, I have a base class where I aim to define shared functionality and a series of subclasses w ...

What is the process for transferring an excel file into MySQL through node.js?

Looking for guidance on how to upload data from an Excel sheet into MySQL using express and Node.js. Can anyone provide tips, examples, or helpful links? ...