【发布时间】:2018-08-04 01:28:02
【问题描述】:
我正在使用 node v9.5,sequelize v4.33(postgres 方言)。
我有两个一流的模型:Driver(特定人)和Car(通用品牌+模型组合)。到目前为止,它们已通过多对多连接表连接起来。现在我想开始跟踪该连接表上的其他属性,但是在声明这些关系以便它们实际工作时遇到了麻烦。
const Driver = sqlz.define('Driver', {
id: { primaryKey: true, type: DataTypes.UUID },
name: DataTypes.string
})
const Car = sqlz.define('Car', {
id: { primaryKey: true, type: DataTypes.UUID },
make: DataTypes.string,
model: DataTypes.string
})
// old associations; worked great when requirements were simpler
Driver.belongsToMany(Car, {
through: 'DriverCar',
as: 'carList',
foreignKey: 'driverId'
})
Car.belongsToMany(Driver, {
through: 'DriverCar',
as: 'driverList',
foreignKey: 'carId'
})
现在我想开始跟踪有关汽车与其驾驶员之间关系的更多信息,例如该特定汽车的颜色。
第 1 步:我更新迁移脚本,向连接表添加一个新列,如下所示:
queryInterface.createTable( 'DriverCar', {
driverId: {
type: sqlz.UUID,
allowNull: false,
primaryKey: true,
references: {
model: 'Driver',
key: 'id'
}
},
carId: {
type: sqlz.UUID,
allowNull: false,
primaryKey: true,
references: {
model: 'Car',
key: 'id'
}
},
createdAt: {
type: sqlz.DATE,
allowNull: false
},
updatedAt: {
type: sqlz.DATE,
allowNull: false
},
// new column for join table
color: {
type: Sequelize.STRING
}
})
第二步:我为DriverCar定义了一个新的sqlz模型:
const DriverCar = sqlz.define('DriverCar', {
color: DataTypes.string
})
(我假设我只需要定义有趣的属性,driverId 和 carId 仍然会从将要定义的关联中推断出来。)
第 3 步:我需要更新 Driver、Car 和 DriverCar 之间存在的关联。
这就是我卡住的地方。我已尝试更新现有关联,如下所示:
Driver.belongsToMany(Car, {
through: DriverCar, // NOTE: no longer a string, but a reference to new DriverCar model
as: 'carList',
foreignKey: 'driverId'
})
Car.belongsToMany(Driver, {
through: DriverCar, // NOTE: no longer a string, but a reference to new DriverCar model
as: 'driverList',
foreignKey: 'carId'
})
这执行没有错误,但是当我尝试driver.getCarList() 时,没有从连接表中获取新的color 属性。 (Sqlz 被配置为记录每个 SQL 语句,并且我已经验证没有请求连接表中的属性。)
因此,我尝试更明确地阐明这种关系,将Driver 关联到DriverCar,然后将Car 关联到DriverCar:
// Driver -> Car
Driver.hasMany(DriverCar, {
as: 'carList',
foreignKey: 'driverId'
})
// Car -> Driver
Car.hasMany(DriverCar, {
foreignKey: 'carId'
})
我还告诉 sqlz DriverCar 不会有标准的行 ID:
DriverCar.removeAttribute('id')
此时,请求驾驶员的 carList (driver.getCarList()) 似乎可行,因为我可以看到在 SQL 中获取连接表道具。但保存失败:
driverModel.setCarList([ carModel1 ])
UPDATE DriverCar
SET "driverId"='a-uuid',"updatedAt"='2018-02-23 22:01:02.126 +00:00'
WHERE "undefined" in (NULL)
错误:
SequelizeDatabaseError: column "undefined" does not exist
我认为发生此错误是因为 sqzl 不了解识别连接表中行的正确方法,因为我未能建立必要的关联。坦率地说,我不确定我是否正确地做到了这一点。我是 ORM 的新手,但我希望我需要指定 4 个关联:
-
Driver->DriverCar -
DriverCar->Car -
Car->DriverCar -
DriverCar->Driver
回顾一下:我有 2 个一流的实体,以多对多的关系加入。我正在尝试向关系中添加数据,发现 ORM 需要以不同的方式定义这些关联,并且在阐明新关联时遇到了麻烦。
【问题讨论】:
-
这是 sequelize 不太出彩的地方之一。您仍然应该能够找到 Driver 并包含 Cars,它应该会带来所有字段。在查询中执行(使用包含)而不是使用魔术方法
-
@yBrodsky:感谢您的提示。我相信我知道您所说的“而不是使用魔术方法”是什么意思,但我必须做更多的研究才能兑现您的建议。
-
我应该补充一下,关于 sequelize 的这个问题表明
include方法不起作用:github.com/sequelize/sequelize/issues/9094 -
这里仍然没有运气。如果有人发现这个,我仍然会很感激帮助。
-
pastebin.com/qT9D4KXE 这不行吗?