[英]Many to one association in sequelize
我有兩個表表 1 (D) 和表 2 (P)
表 1 的每一行可以有一個或多個從表 2(P) 映射的行
例如:D1 -> P1,P2,P3 D2 -> P1,P3
如何在 sequelize 中實現從表 1 到表 2 的多對一關聯。請幫助。
我在讓 Sequelize 也能正常工作時遇到了很多麻煩。 這是我的做法。
假設您使用 sequelize-cli: https://www.npmjs.com/package/sequelize-cli :
npm install --save-dev sequelize-cli
npx sequelize-cli init
這使我們的項目接下來使用遷移來啟動我們的 D 和 P 表以及 D 和 P 模型。
npx sequelize-cli model:generate --name D --attributes firstVariable:string,secondVariable:string,thirdVariable:string
// i made p the same way
生成器所能做的就是為表命名、聲明變量並賦予它們類型。 接下來我們編輯 D 和 P 遷移文件以匹配我們想要的表。 我們還配置我們的數據庫連接。 看到遷移文件后,編輯遷移文件非常直觀。 這是我制作的文件。
//simple as you can get changes to config.json to
{
"development": {
"storage" : "/wherever/im/putting/mydatabase.db",
"dialect": "sqlite"
}
}
//create d
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('D', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstVariable: {
type: Sequelize.STRING
},
secondVariable: {
type: Sequelize.STRING
},
anotherVariable: {
type: Sequelize.STRING
}//,
// createdAt: {
// allowNull: false,
// type: Sequelize.DATE
// },
// updatedAt: {
// allowNull: false,
// type: Sequelize.DATE
// }
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('D');
}
};
//create P
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('P', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstVariable: {
type: Sequelize.STRING
},
secondVariable: {
type: Sequelize.STRING
},
anotherVariable: {
type: Sequelize.STRING
},
Did: {
type: Sequelize.INTEGER,
references: {
model: 'D',
key: 'id'
}
}//,
// createdAt: {
// allowNull: false,
// type: Sequelize.DATE
// },
// updatedAt: {
// allowNull: false,
// type: Sequelize.DATE
// }
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('P');
}
};
甚至在編輯 Create P 和 Create D 之前運行 npx sequelize-cli db:migrate 來測試您的連接。 當連接正常並且您獲得表時,然后繼續運行 migrate 以測試您對 Create P 和 Create D 的更改。只需刪除所有表並再次運行 migrate。 第一個技巧是將適當的外鍵添加到遷移文件中。 這是P.Did。 參考選項很重要。 我認為遷移文件創建了所有的數據庫結構。 接下來我們調整model文件; 注釋在代碼中:
//D.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class D extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
D.hasMany(models.P, {foreignKey: "Did", onDelete: 'CASCADE', onUpdate: 'CASCADE'}); // https://sequelize.org/master/manual/assocs.html
}
};
D.init({
firstVariable: DataTypes.STRING,
secondVariable: DataTypes.STRING,
anotherVariable: DataTypes.STRING
}, {
sequelize,
timestamps: false, //timestamps may need to be first option?
modelName: 'D',
tableName: 'D'
});
return D;
};
//P.js
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class P extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
P.belongsTo(models.D, {onDelete: 'CASCADE', onUpdate: 'CASCADE', foreignKey: 'Did'}); //not setting onUpdate and onDelete, if also doesn't work on your system set in database instead
}
};
P.init({ //I make sure all P variables are in init, but I have not test if adding the foreign key is necessary here
firstVariable: DataTypes.STRING,
secondVariable: DataTypes.STRING,
anotherVariable: DataTypes.STRING,
Did: DataTypes.INTEGER
}, {
sequelize,
timestamps: false, //otherwise sequelize assumes timestamps are in the table and writes queries accordingly
modelName: 'P',
tableName: 'P'
});
return P;
};
技巧 2 或技巧 1 的第二部分是將外鍵選項添加到 D.hasmany 和 P.belongsto。 這避免了許多陷阱。
最后是一些測試代碼:
//index.js
//index.js to test code
const db = require('./models');
const asyncouterFunction = async function() {
const D = db.D;
const P = db.P;
const d1 = await D.create({firstVariable: "A", secondVariable:"B", anotherVariable: "C"});
const p1 = await P.create({firstVariable: "a", secondVariable:"b", anotherVariable: "c"});
const p2 = await P.create({firstVariable: "a", secondVariable:"b", anotherVariable: "c"});
await d1.addPs([p1,p2]);
let count = await d1.countPs();
console.log(count);
await d1.removeP(p2);
count = await d1.countPs();
console.log(count)
}
asyncouterFunction();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.