首页 > 解决方案 > postgresql with Node js Sequalize One-To-One 允许模型 1 的多个实例与模型 2 的同一个实例相关联

问题描述

我正在尝试使用节点 js 和 sequalize 创建不同的模型关联,但在创建一对一关联时遇到问题。

文档说使用 .hasOne() 和 .belongsTo() 来创建一对一。从 sequalize 文档中:

Foo.hasOne(Bar);
Bar.belongsTo(Foo);

产生以下 sql 语句:

CREATE TABLE IF NOT EXISTS "foos" (
  /* ... */
);
CREATE TABLE IF NOT EXISTS "bars" (
  /* ... */
  "fooId" INTEGER REFERENCES "foos" ("id") ON DELETE SET NULL ON UPDATE CASCADE
  /* ... */
);

好吧,现在一对一关联不应该有一个约束来防止多个“条”引用同一个“Foo”吗?因为我在生成的 sql 中看不到这样的约束,我已经尝试了代码,是的,我可以有多个“Bars”指向一个“Foo”,这使它成为一对多,不是吗?

同样来自文档的一对多关联与以下代码:

Team.hasMany(Player);
Player.belongsTo(Team);

产生以下 sql 语句:

CREATE TABLE IF NOT EXISTS "Teams" (
  /* ... */
);
CREATE TABLE IF NOT EXISTS "Players" (
  /* ... */
  "TeamId" INTEGER REFERENCES "Teams" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
  /* ... */
);

这与一对一生成的 sql 语句相同。我是不是错过了什么。请有人帮忙。

我期望“fooId”列具有独特的约束,以防止多个“条”与单个“foo”相关

标签: node.jspostgresqlsequelize.js

解决方案


奇怪的是,创建任何约束以阻止多个对象与同一个对象关联Foo.hasOne(Bar)是不够的,至少在. 但是,对象 where和where的实例方法存在差异(请参阅关联文档)。具体来说,您将拥有:BarFooversion 6 of sequelizeFooFoo.hasOne(Bar)Foo.hasMany(Bar)

Foo.hasOne(酒吧)

fooInstance.getBar()
fooInstance.setBar()
fooInstance.createBar()

相对

Foo.hasMany(酒吧)

fooInstance.getBars()
fooInstance.countBars()
fooInstance.hasBar()
fooInstance.hasBars()
fooInstance.setBars()
fooInstance.addBar()
fooInstance.addBars()
fooInstance.removeBar() fooInstance.removeBars()
fooInstance.createBar()

话虽如此,可以将唯一约束添加到模型定义中。例如,

let Parent = sequelize.define('parent', {
        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        name: DataTypes.STRING
    },
    {
        tableName: 'parents',
        timestamps: false
    })

let Child = sequelize.define('child', {
        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        name: DataTypes.STRING,
        parentId: {
            type: DataTypes.INTEGER,
            references: {
                model: Parent,
                key: 'id'
            },
            unique: true
        }
    },
    {
        tableName: 'children',
        timestamps: false
    })

Parent.hasOne(Child, {
    foreignKey: 'parentId',
    sourceKey: 'id'
})
Child.belongsTo(Parent, {
    foreignKey: 'parentId',
    targetKey: 'id'
})

上面截断的导入部分是如下行:

唯一:真

这将导致:

CREATE TABLE IF NOT EXISTS "children" ("id"   SERIAL , "name" VARCHAR(255), "parentId" INTEGER UNIQUE REFERENCES "parents" ("id") ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY ("id"));

推荐阅读