Node, Sequelize, Sync модели, сила смешения: правда / ложь - PullRequest
1 голос
/ 24 апреля 2019

Я в замешательстве (снова).

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

Теперь я доволен своей таблицей 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?

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Выборочная синхронизация в 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

0 голосов
/ 25 апреля 2019

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

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

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

Учитывая model definition, как в ОП.
Файл: 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.log('sequelize model:',name);
});

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

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

Это приводит к тому, что user NOT удаляется, но company IS удаляется.

Вот вывод консоли из цикла:

> 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, но сейчас я бы предпочел выполнить начальное моделирование в файлах определений по мере необходимости.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...