Sequelize или MySql создает дополнительные таблицы, соединения таблиц отсутствуют на диаграмме EER - PullRequest
0 голосов
/ 29 декабря 2018

Обновление 01/02

Пожалуйста, смотрите скриншот.Я сократил приложение до 2 таблиц: Адреса и Пользователи.

Запуск sequelize db: миграция с миграциями / моделями ниже создает дополнительную таблицу «пользователей».Смотрите раздел каталога.При нажатии на всплывающее сообщение «пользователи» «Таблица, которую вы пытаетесь редактировать, является заглушкой только для модели, созданной для представления отсутствующих внешних таблиц, на которые ссылаются внешние ключи.»

На диаграмме нет дополнительных «пользователей».Таблица.Не устанавливается соединение для Addresses.userId с Users.id, как это должно быть.

У кого-нибудь есть мысли по поводу того, почему или как это исправить?

  • Работа в Macbook OS X10.14.2
  • Версия Sequelize: Sequelize CLI [Узел: 10.7.0, CLI: 5.4.0, ORM: 4.42.0]
  • Версия сервера MySql: 8.0.13
  • Версия MySql Workbench также: 8.0.13

MySql Workbench shows extra 'users' table

Обновление 12/30

В MySql Workbench Database> Reverse Engineer отображает диаграмму таблиц, но линии внешнего / первичного ключа не отображаются.Механизм БД - InnoDB.

Я использую миграцию / модели Sequelize для создания БД и связей.Например, таблица «Адреса» имеет внешний ключ «userId» для таблицы «Пользователи».

В разделе таблиц «Каталог» схемы EER каким-то образом есть таблица «Пользователи» и таблица «пользователи».Внешний ключ Addresses.userId указывает на таблицу 'users' в нижнем регистре, таблицу, которая не должна существовать.Таблица в нижнем регистре не отображается ни на диаграмме, ни в списке таблиц БД в разделе схемы, она появляется только в разделе таблиц каталога.

Также есть две другие пары таблиц: свойство / свойство,PropertyClass / PropertyClass.Ни в одной другой таблице нет дубликатов.У пользователей и PropertyClasses есть объединенная таблица UserPropertyClasses.

Есть идеи, почему это может происходить или как это предотвратить?

Версия сиквелиза: Sequelize CLI [Node: 10.7.0, CLI: 5.4.0, ORM: 4.42.0]

Версия сервера MySql: 8.0.13

Версия MySql Workbench также: 8.0.13

Вот модель адреса:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Address = sequelize.define('Address', {
    userId: {
      type: DataTypes.INTEGER,
      validate: {
        notNull: true
      }
    },
    street1: {
      type: DataTypes.STRING,
      validate: {
        notEmpty: true
      }
    }
  }, {
    paranoid: true
  });

  Address.associate = function(models) {
    Address.belongsTo(models.User, {
      as: 'user',
      foreignKey: 'userId'
    })
  }
  return Address;
};

Вот миграция адресов:

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Addresses', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      userId: {
        allowNull: false,
        type: Sequelize.INTEGER,
        references: {
          model: 'Users',
          key: 'id'
        }
      },
      street1: {
        allowNull: false,
        type: Sequelize.STRING(50)
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      deletedAt: {
        allowNull: true,
        defaultValue: null,
        type: Sequelize.DATE
      }
    })
    .then(async () => {
      return await Promise.all([
        queryInterface.addIndex('Addresses', [ 'userId' ]),
      ])
    });
  }

Модель пользователя:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    firstname: {
      type: DataTypes.STRING,
      validate: {
        notEmpty: true
      }
    }
  }, {
    paranoid: true
  });

  User.associate = function(models) {
    User.hasOne(models.Address, {
      as: 'address',
      foreignKey: 'userId'
    })
  };

  return User;
};

Вот миграция пользователя:

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      firstname: {
        allowNull: false,
        type: Sequelize.STRING(50)
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      deletedAt: {
        allowNull: true,
        defaultValue: null,
        type: Sequelize.DATE
      }
    })
    .then(async () => {
      return await Promise.all([
        queryInterface.addIndex('Users', [ 'firstname' ]),
      ]);
    })
  }

1 Ответ

0 голосов
/ 06 января 2019

Публикуем здесь то, что я обнаружил, если это помогает другим.

Документы Mysql утверждают, что имена таблиц должны быть строчными при использовании InnoDB.

Если вы используете таблицы InnoDB, вам следуетустановите эту переменную равной 1 на всех платформах, чтобы принудительно преобразовать имена в нижний регистр.

https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_lower_case_table_names

Здесь внесены изменения, чтобы исключить создание дополнительных таблиц и отобразить диаграмму со связью.соединения:

  • Имена таблиц в виде змеи во множественном числе
  • Имена столбцов таблицы и их ссылки в виде змеи в единственном числе
  • Модель и имя PascalCase в единственном числе
  • Атрибут моделиИмена camelCase с полевым регистром «змей» в единственном числе
  • Модель, созданная с опцией «tableName» регистр змей во множественном числе
  • Модель с опцией «подчеркнут» true
  • Ассоциация модели с «as»Псевдоним 'alias and' foreignKey '

Пример миграции:

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('addresses', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      user_id: {
        allowNull: false,
        type: Sequelize.INTEGER,
        references: {
          model: 'users',
          key: 'id'
        }
      },
      street1: {
        allowNull: false,
        type: Sequelize.STRING(50)
      }
      created_at: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updated_at: {
        allowNull: false,
        type: Sequelize.DATE
      },
      deleted_at: {
        allowNull: true,
        defaultValue: null,
        type: Sequelize.DATE
      }
    })
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('addresses');
  }
};

Пример модели:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Address = sequelize.define('Address', {
    userId: {
      type: DataTypes.INTEGER,
      field: 'user_id',
      allowNull: false,
      validate: {
        notNull(value) {
          if (value == null) {
            throw new Error('Missing user id')
          }
        }
      }
    },
    street1: {
      type: DataTypes.STRING,
      field: 'street1',
      validate: {
        notEmpty: true
      }
    }
  }, {
    tableName: 'addresses',
    paranoid: true,
    underscored: true
  });

  Address.associate = function(models) {

    Address.belongsTo(models.User, {
     as: 'user',
     foreignKey: 'user_id'
    })
  }

  return Address;
};
...