Лучший способ программно добавить таблицы в узел и приложение express с помощью Sequelize - PullRequest
0 голосов
/ 03 марта 2020

Я немного исследовал это, но не могу найти правильный ответ. Я создаю персональное приложение для планирования с помощью узла Express и Sequelize. Чтобы предоставить пользователям как можно больше гибкости, я хочу, чтобы приложение динамически генерировало таблицы для пользовательских бюджетов. Пользователи могут создавать столько бюджетов, сколько захотят, и добавлять до 10 или 12 столбцов. Я думал об использовании необработанного запроса Sequelize, но его динамическая генерация является грязной, и я не уверен, что это очень хорошая практика. Должен ли я использовать миграцию и библиотеку umzug? Дело в том, что я все еще довольно новичок в разработке на стороне сервера и в базах данных, поэтому мне просто нужно немного руководства по этому вопросу. Вот мой текущий необработанный запрос. Я еще не тестировал его, так как собирал другие основные компоненты приложения.

/* Handle dynamic budget table creation and queries */

const Db = require('./lib/Db.js');

module.exports = class Budget extends Db
{
    /**
     * Create a new budget table
     * @param {String} name - budget name
     * @param {Object} columns - object of column names and their values
     * @param {String} user - user name
     * @param {Number} userId - user id
     */
    async createNewBudget(name, columns, user, userId)
    {
        let query = `CREATE TABLE ${name}_budget (`;
        for (let key in columns) {
            query += `${key} NUMERIC, `;
        }
        query += ")";
        await this.db.sequelize.query(query);
        let insert = `INSERT INTO ${name}_budget(`;
        for (let key in columns) {
            insert += `${key}, `;
        }
        insert += ") VALUES (";
        for (let key in columns) {
            insert += `${columns[key]}, `;
        }
        insert += ")";
        await this.db.sequelize.query(insert);
    }
}

Класс Db - это простой класс, который делает доступным экземпляр sequelize:

/* Base class for all classes interacting with the database via raw queries */

module.exports = class Db 
{
    constructor()
    {
        this.db = require('../models/index.js');
    }
}

У меня есть эти файлы в моем каталоге lib. Я просто чувствую, что то, что я делаю, не так хорошо. Любые полезные предложения будут с благодарностью.

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Мы можем определить модель в одном файле, скажем, модели / бюджет. js:

module.exports = function (sequelize, DataTypes) {

    const Budget = sequelize.define('budget', {
        id: {
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
            primaryKey: true,
        },        
        category: {
            type: DataTypes.STRING,
            allowNull: true,
            defaultValue: null,
        },
        name: {
            type: DataTypes.STRING,
            allowNull: true,
            defaultValue: null,
        },
        ...,
        version: {
            type: DataTypes.INTEGER,
            defaultValue: 0,
            allowNull: false,
        },
    }, {
        version: true,
        paranoid: true        
    });

    return Budget;
};

Затем создайте файл "миграции" , который загружает модель в БД :

'use strict';

const models = require('../models');

module.exports = {
    up: function (queryInterface) {
        return queryInterface.createTable(models.Budget.tableName, models.Budget.rawAttributes);
    },

    down: function (queryInterface) {
        return queryInterface.dropTable(models.Budget.tableName);
    },
};
0 голосов
/ 03 марта 2020

Мне немного любопытно, почему вы хотите, чтобы пользователь мог создавать новые таблицы ... Я думаю, вам следует использовать миграцию для настройки исходной базы данных и продумать ее до такой степени, чтобы у пользователей были идентификаторы , тогда у вас есть таблица user_budget, которая является соединением многих ко многим с бюджетом и множеством вариантов после этого, дизайн базы данных требует некоторого планирования, но это не ракетостроение, и если / когда вы не понимаете это правильно, это не слишком трудно изменить ... postgres, mySQL et c отлично справляются с обработкой большого количества строк и множеством взаимосвязей, но я думаю, что вы, возможно, создаете кучу технических долгов и не масштабируемое решение для создания новых таблиц для новых бюджетов это не нужно для РСУБД. Вы создаете новую таблицу для чего-то, что может быть просто парой строк в хорошо спроектированной БД

...