【问题标题】:Change Sequelize default foreign key with through tables使用直通表更改 Sequelize 默认外键
【发布时间】:2021-05-19 03:39:43
【问题描述】:

我有两张桌子,appsservices。在services 上,PRIMARY KEY 设置为名为@9​​87654326@ 的字段。 我在这两个名为apps_services 的表之间创建了一个直通表,其中appIdserviceId

 appId: {
        type: Sequelize.UUID,
        references: {
          model: 'apps',
          key: 'id'
        }
      },

      serviceId: {
        type: Sequelize.STRING,
        references: {
          model: 'services',
          key: 'orn'
        }
      },

但这里有一个问题,当我使用app.addService(foundService); 时(这会在该应用程序实例和 foundService 之间建立关系)。当我使用节点调试器时,我发现sequelize 尝试将id 插入serviceId 而不是orn

Executing (default): INSERT INTO "apps_services" ("id","appId","serviceId","createdAt","updatedAt") VALUES ('8d85f9b9-b472-4165-a345-657a0fe0d8ad','49f3daa4-1df4-4890-92f8-9a06f751ffb7','8cab340d-d11b-4e3b-842c-aeea9a28c368','2021-02-16 00:22:17.919 +00:00','2021-02-16 00:22:17.919 +00:00') RETURNING "id","appId","serviceId","userId","selfGranted","createdAt","updatedAt";

括号中的第三个值,问题是id不是foreignKey而是orn

下面是service 表,我们可以看到orn 列,它是链接到apps_services 表的主键和外键。

有没有办法强制 sequelize 使用orn 字段?

module.exports = (sequelize, DataTypes) => {
const apps_services = sequelize.define('apps_services', {
    id: {
        type: DataTypes.UUID,
        defaultValue: new DataTypes.UUIDV4(),
        unique: true,
        primaryKey: true
    },
    appId: {
        type: DataTypes.UUID,
    },

    serviceId: {
        type: DataTypes.STRING,
    },
    userId: {
        type: DataTypes.UUID
    },
    selfGranted: DataTypes.BOOLEAN
}, {
    timestamps: true
});

apps_services.associate = function (models) {
    models.apps.belongsToMany(models.services, {
        through: apps_services
    });

    models.services.belongsToMany(models.apps, {
        through: apps_services
    });
};
//apps_services.sync({alter: true});

return apps_services;

};

// 这是 apps_services 迁移

module.exports = {
up: async (queryInterface, Sequelize) => {
 await queryInterface.createTable('apps_services', {
   id:{
     type: Sequelize.UUID,
     defaultValue: new Sequelize.UUIDV4(),
     unique: true,
     primaryKey: true
 },
   appId: {
     type: Sequelize.UUID,
     references: {
       model: 'apps',
       key: 'id'
     }
   },

   serviceId: {
     type: Sequelize.STRING,
     references: {
       model: 'services',
       key: 'orn'
     }
   },

   userId: {
     type: Sequelize.UUID,
     references: {
       model: 'Users',
       key: 'id'
     }
   },

   createdAt: {
     allowNull: false,
     type: Sequelize.DATE
   },
   updatedAt: {
     allowNull: false,
     type: Sequelize.DATE
   },
   selfGranted: Sequelize.BOOLEAN,
 });
},

down: async (queryInterface, Sequelize) => {
 await queryInterface.dropTable('apps_services');
}
};

下面是服务表

【问题讨论】:

  • 请在问题中添加模型文件,这样容易理解,可以更好地帮助你。
  • @AbhishekShah 我已经添加了它

标签: node.js postgresql express orm sequelize.js


【解决方案1】:

是的,您可以从对面的表格中提及要使用的字段。

apps_services.associate = function (models) {
    
    // you can move this association to apps model file
    models.apps.belongsToMany(models.services, {
        // Reference: https://sequelize.org/master/class/lib/model.js~Model.html#static-method-belongsToMany
        through: 'apps_services',
        foreignKey: 'appId', // <-- add this
    });
    
    // you can move this association to services model file
    models.services.belongsToMany(models.apps, {
        through: 'apps_services',
        foreignKey: 'serviceId', // <-- add this - name of field in through table
        otherKey: 'orn', // <-- add this - name of field in source table
    });
    
    /**
     * new relation below just to complete the Many to Many relation
     */
    // you can add this association in app_services model file
    models.apps_services.belongsTo(models.services, {
        // Reference: https://sequelize.org/master/class/lib/model.js~Model.html#static-method-belongsTo
        foreignKey: 'serviceId', // <--- name of field in source table
        targetKey: 'orn', // <--- name of field in target table
    });
    
    // you can add this association in app_services model file
    models.apps_services.belongsTo(models.apps, {
        foreignKey: 'appId', // <--- name of field in source table
        // targetKey: 'id', //(not needed as already primary key by default) <--- name of field in target table
    });

};

【讨论】:

  • 我做了这些,但是当我在终端的输出上运行apps_services.sync({alter: true}); 时,我看到了这个Executing (default): ALTER TABLE "apps_services" ADD FOREIGN KEY ("serviceId") REFERENCES "services" ("id") ON DELETE CASCADE ON UPDATE CASCADE; 它仍然在服务表上将serviceId 链接到id
  • 我现在已经解决了,我不知道 sequelize 试图做什么,但似乎它决定了从foreignKey 的名称链接到foreignKey 的内容。如果名称中有Id,例如serviceId,它只会在set() 期间尝试将其链接到id 字段。我所做的是将名称更改为serviceOrn 而不是otherKey : 'orn' 我使用sourceKey: 'orn'
猜你喜欢
  • 2015-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2022-09-25
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
相关资源
最近更新 更多