更新01/02
请查看屏幕截图。我将应用程序缩减为2个表:地址和用户。
使用下面的迁移/模型运行sequelize db:migrate会创建一个额外的“用户”表。请参阅目录部分。单击“用户”会弹出消息“您要编辑的表是仅用于模型的存根,用于表示缺少由外键引用的外部表。”
图没有额外的“用户”表。没有像应有的那样为Useres.id绘制Addresses.userId的连接。
有人对为什么或如何解决有任何想法吗?
更新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' ]),
]);
})
}
答案 0 :(得分:0)
在这里张贴我发现对他人有帮助的内容。
Mysql文档指出,使用InnoDB时,表名应小写。
如果使用的是InnoDB表,则应在所有平台上将此变量设置为1,以强制将名称转换为小写。
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_lower_case_table_names
此处进行了一些更改,以消除额外的表创建并通过关系连接呈现图:
迁移示例:
'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;
};