Sequelize или MySql создает дополнительные таблицы, соединения таблиц отсутствуют на диаграмме EER

0

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

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

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

Диаграмма не имеет дополнительной таблицы "пользователей". Соединение для Addresses.userId с Users.id не рисуется так, как должно быть.

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

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

Изображение 174551

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

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

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

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

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

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

Версия Sequelize: Sequelize CLI [Узел: 10.7.0, CLI: 5.4.0, ORM: 4.42.0]

MySql Server версия: 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' ]),
      ]);
    })
  }
  • 0
    Я думаю, что вам нужно определить ссылки (ограничения) в миграции, а также, если вы используете миграции, вы используете миграции?
  • 0
    Ссылка в миграции. Я обновлю вопрос
Показать ещё 2 комментария
Теги:
mysql-workbench
sequelize.js

1 ответ

0

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

В документации 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" и "змеей" 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;
};

Ещё вопросы

Сообщество Overcoder
Наверх
Меню