sequelize或mysql创建额外的表,eer图中缺少表连接

llmtgqce  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(434)

更新01/02
请看截图。我把app缩减为两个表:地址和用户。
运行下面的sequelize db:migrate with migrations/models会创建一个额外的“users”表。请参见目录部分。单击“users”会弹出消息“您试图编辑的表是一个仅用于模型的存根,创建此存根是为了表示外键引用的缺少的外部表。”
图表没有额外的“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服务器版本:8.0.13
mysql工作台版本也是:8.0.13

更新12/30
在mysql工作台中,database>reverse engineer呈现一个表图,但不绘制外键/主键线。数据库引擎是innodb。
我使用sequelize迁移/模型来创建数据库和关系。例如,addresses表具有users表的“userid”外键。
在eer图的目录部分的表中,不知何故有一个“users”表和“users”表。外键addresses.userid指向小写的“users”表,该表不应存在。小写的表不会出现在图表中,也不会出现在schema部分的db table列表中,它只出现在表的catalog部分。
还有另外两对表:property/property、propertyclass/propertyclass。没有其他表有重复项。users和propertyclasses有一个联接表userpropertyclasses。
你知道为什么会发生这种情况,或者如何预防吗?
sequelize版本:sequelize cli[节点:10.7.0,cli:5.4.0,orm:4.42.0]
mysql服务器版本:8.0.13
mysql工作台版本也是: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' ]),
      ]);
    })
  }
tkqqtvp1

tkqqtvp11#

在这里张贴我的发现,如果它有助于其他人。
mysql docs声明在使用innodb时表名应该是小写的。
如果您使用的是innodb表,那么应该在所有平台上将此变量设置为1,以强制将名称转换为小写。
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_lower_case_table_names
以下是为消除额外的表创建和使用关系连接呈现图表所做的更改:
表名大小写复数形式
表列名及其引用
型号和名称pascalcase singular
“field”snake case单数形式的模型属性名称
使用“tablename”选项创建的模型大小写复数
使用选项“下划线”创建的模型为真
“as”别名和“foreignkey”snake case的模型关联
迁移示例:

'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;
};

相关问题