Node, Sequelize, Sync model, сила микширования: true/false

Я в замешательстве (опять же).

При определении таблиц базы данных (MySQL) с помощью Sequelize я хочу сделать sync(forced:true), чтобы удалить/создать таблицы. Все идет нормально.

Теперь я доволен своей user таблицей и не хочу ее сбрасывать при каждом прогоне, пока продолжаю определять другие таблицы.

Итак, я хотел бы установить флажок на user варианты, sync: {forced: false}

module.exports = (sequelize, DataTypes) => {
  let Schema = sequelize.define(
    "user",
    {
      id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
      },
      BlaBla:{}
    },
    { // options
      sync: {force: false},
      freezeTableName: true,
      timestamps: true
    });
  return Schema;
};

Это не работает. Таблица удаляется/создается при каждом запуске.

Переходим к определению моей companyтаблицы.

module.exports = (sequelize, DataTypes) => {
  let Schema = sequelize.define(
    "company",
    {
      id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
      },
      BlaBla:{}
    },
    { // options
      sync: {force: true},
      freezeTableName: true,
      timestamps: false
    });
  return Schema;
};

Вопрос

  • Как выборочно синхронизировать таблицы на основе параметров sequelize.define?

1. Я не могу найти документ по использованию синхронизации в качестве параметра в определении. Вы уверены, что это разрешено? 2. Если вы синхронизируете() таблицы по отдельности (вместо использования sequenceize.sync() для всех таблиц), вы можете «принудительно» использовать разные таблицы для каждой таблицы).

KenOn10 24.04.2019 17:32
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
2
1
5 174
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Выборочная синхронизация в sequelize.define() не поддерживается. Подробнее см. в Конфигурация определения модели. В другом месте вашего проекта у вас должен быть вызов sequelize.sync({force: true}), который синхронизирует все модели. Вы должны исправить это в первую очередь, так как это принудительно синхронизирует все ваши модели.

После исправления у вас есть несколько вариантов дальнейших действий:

1: Используйте миграции в будущем. Каждое добавление или изменение вашей схемы фиксируется при миграции, поэтому вы можете развертывать каждое изменение без повторной синхронизации других. См. http://docs.sequelizejs.com/manual/migrations.html

2: Синхронизируйте каждую таблицу отдельно, как вы предлагаете. Вам нужно будет вызывать метод sync() для каждой модели отдельно, например:

const user = require('./user');
const company = require('./company');
company.sync();
compant.sync({force:true});

Это может быть удобно для ранней разработки, но по мере того, как вы продвигаетесь в проекте и начинаете выпуск, миграция должна быть вашим предпочтительным методом для развертывания изменений схемы.

См. http://docs.sequelizejs.com/manual/models-definition.html#database-synchronization

Ответ принят как подходящий

Хорошо, после хорошего ночного сна мой мозг снова начинает работать.

  • Первый. Я не понимаю, почему все примеры загрузки моделей создают db object
    • держать все модели. db[model.name] = model
    • ссылка на пакет Sequelize db.Sequelize = Sequelize
    • ссылка на подключение db.sequelize = sequelize

когда экземпляр const sequelize = new Sequelize() - это все, что вам нужно.

Учитывая model definition как в OP.
Файл: app/models/user.js

module.exports = (sequelize, DataTypes) => {
  let Schema = sequelize.define(
    "user",
    {
      id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
      },
      BlaBla:{}
    },
    { // options
      sync: {force: false},
      freezeTableName: true,
      timestamps: true
    });
  return Schema;
};

И такой бутстрап:
Файл: config/sequelize.js

const Sequelize = require("sequelize");

const sequelize = new Sequelize(config.dbname, config.dbuser, config.dbpass, {
    dialect: "mysql",
    host: config.dbhost,
    port:    3306,
    define: {
        engine: 'MYISAM',
        timestamps: true,
      }
  });

fs
  .readdirSync(path.join(config.models))
  .filter(file => ~file.indexOf('.js'))
  .forEach((file) => {
    let model = sequelize["import"](path.join(config.models, file));
    model.sync(model.options.sync);
  });

module.exports = sequelize;

Затем у вас есть синхронизация для каждой модели.

Затем в server.js:

const sequelize = require(join(__dirname,"config/sequelize"));
/* debug */
Object.keys(sequelize.models).forEach(function(name) {
    console.info('sequelize model:',name);
});

console.info('Checking DB connection...');
sequelize
  .authenticate()
  .then(() => {
    console.info('Successfully connected to:', config.dbname);
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
    process.exit;
  });

const User = sequelize.model('user');

Это приводит к тому, что userНЕТ отбрасывается, но companyЯВЛЯЕТСЯ отбрасывается.

Вот вывод консоли из прогона:

> node server.js

config/index.js { dbhost: '192.168.1.70',
  dbport: 3306,
  dbname: 'dbdev',
  dbuser: 'dbdev',
  dbpass: '********',
  mode: 'development',
  root: 'C:\\Workspace\\Github\\******',
  models: 'C:\\Workspace\\Github\\******\\app\\models',
  sync: false }

Creating DB connection...
Loading Schema: company
company sync { force: true }
Loading Schema: user
user sync { force: false }
sequelize model: company
sequelize model: user
Checking DB connection...
Server fetching: user
Executing (default): SELECT 1+1 AS result
Executing (default): DROP TABLE IF EXISTS `company`;
Executing (default): CREATE TABLE IF NOT EXISTS `user` (`id` INTEGER UNSIGNED auto_increment , `login` VARCHAR(45) UNIQUE, `password` VARCHAR(255), `fname` VARCHAR(45), `lname` VARCHAR(45), `email` VARCHAR(128), `phone` VARCHAR(20), `company` INTEGER UNSIGNED, `createdby` INTEGER UNSIGNED, `access` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=MYISAM;
Successfully connected to: dbdev
Executing (default): SHOW INDEX FROM `user`
Executing (default): CREATE TABLE IF NOT EXISTS `company` (`id` INTEGER auto_increment , `name` VARCHAR(255), `type` INTEGER, `createdby` INTEGER, `access` INTEGER, PRIMARY KEY (`id`)) ENGINE=MYISAM;
Executing (default): SHOW INDEX FROM `company`

Я мог бы взглянуть на migrations, но сейчас я предпочитаю выполнять начальное моделирование в файлах определений по мере необходимости.

Я пропустил какой-то важный момент, или это решение "летает"?

Да, это кажется творческим и разумным способом управлять синхронизацией через определение модели.

Andrew Yochum 25.04.2019 08:01

Другие вопросы по теме