Sequelize或MySql创建额外的表,EER图中缺少表连接

时间:2018-12-29 18:02:56

标签: mysql node.js sequelize.js mysql-workbench

更新01/02

请查看屏幕截图。我将应用程序缩减为2个表:地址和用户。

使用下面的迁移/模型运行sequelize db:migrate会创建一个额外的“用户”表。请参阅目录部分。单击“用户”会弹出消息“您要编辑的表是仅用于模型的存根,用于表示缺少由外键引用的外部表。”

图没有额外的“用户”表。没有像应有的那样为Useres.id绘制Addresses.userId的连接。

有人对为什么或如何解决有任何想法吗?

  • 在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

MySql Workbench shows extra 'users' table

更新12/30

在MySql Workbench中,数据库>逆向工程师呈现表图,但未绘制外键/主键线。数据库引擎是InnoDB。

Am使用Sequelize迁移/模型创建数据库和关系。例如,“地址”表具有“用户”表的“ userId”外键。

在EER图的表的Catalog部分中,以某种方式存在一个'Users'表和'users'表。外键Addresses.userId指向小写的“ users”表,该表不应该存在。小写的表既不会出现在图中,也不会出现在“模式”部分的“数据库表”列表中,而只会出现在表的“目录”部分。

还有另外两对表:属性/属性,PropertyClass / propertyclass。没有其他表重复。用户和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' ]),
      ]);
    })
  }

1 个答案:

答案 0 :(得分: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(带有“ field”蛇格)为单数
  • 使用“ tableName”蛇形复数选项创建的模型
  • 使用选项'underscored'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;
};