Sequelize:带有关联的种子
Posted
技术标签:
【中文标题】Sequelize:带有关联的种子【英文标题】:Sequelize: seed with associations 【发布时间】:2018-07-21 18:45:45 【问题描述】:例如,我有 2 个模型,课程和视频。课程有很多视频。
// course.js
'use strict';
module.exports = (sequelize, DataTypes) =>
const Course = sequelize.define('Course',
title: DataTypes.STRING,
description: DataTypes.STRING
);
Course.associate = models =>
Course.hasMany(models.Video);
;
return Course;
;
// video.js
'use strict';
module.exports = (sequelize, DataTypes) =>
const Video = sequelize.define('Video',
title: DataTypes.STRING,
description: DataTypes.STRING,
videoId: DataTypes.STRING
);
Video.associate = models =>
Video.belongsTo(models.Course,
onDelete: "CASCADE",
foreignKey:
allowNull: false
)
;
return Video;
;
我想用包含视频的课程创建种子。我怎样才能做到?我不知道如何使用包含的视频创建种子。
【问题讨论】:
【参考方案1】:您可以使用 Sequelize 的 queryInterface
下拉到原始 SQL 以插入需要关联的模型实例。在您的情况下,最简单的方法是为课程和视频创建一个播种机。 (注:我不知道你是如何定义主键和外键的,所以我假设视频表有一个字段course_id
。)
module.exports =
up: async (queryInterface) =>
await queryInterface.bulkInsert('courses', [
title: 'Course 1', description: 'description 1', id: 1
title: 'Course 2', description: 'description 2', id: 2
], );
const courses = await queryInterface.sequelize.query(
`SELECT id from COURSES;`
);
const courseRows = courses[0];
return await queryInterface.bulkInsert('videos', [
title: 'Movie 1', description: '...', id: '1', course_id: courseRows[0].id
title: 'Movie 2', description: '...', id: '2', course_id: courseRows[0].id,
title: 'Movie 3', description: '...', id: '3', course_id: courseRows[0].id,
], );
,
down: async (queryInterface) =>
await queryInterface.bulkDelete('videos', null, );
await queryInterface.bulkDelete('courses', null, );
;
【讨论】:
在down
部分中,由于外键约束,我们不应该删除课程列之前的视频列。抱歉,我很挑剔。
请结帐***.com/questions/52227663/…
最新版本会抛出'await is only valid in async function'【参考方案2】:
在bulkInsert
的选项字段中传递 returning: true
时,它将返回创建的对象。
let createdOjects = await queryInterface.bulkInsert("table_name", data_to_be_inserted, returning: true );
此外,您可以传递一个包含您感兴趣的字段的数组,例如ID returning: ['id']
,这将返回创建对象的 ID 数组
let createdIds = await queryInterface.bulkInsert("table_name", data_to_be_inserted, returning: ['id'] );
您也可以使用bulkInsert
循环遍历返回的对象/ID 并插入嵌套对象。
示例代码:
module.exports =
up: async (queryInterface) =>
let courses = ["..."]
let videos = ["..."]
let videoIds = await queryInterface.bulkInsert("courses", courses, returning: ["id"] );
//add courseId to each video object -- depends on your scheme
await queryInterface.bulkInsert("videos", videos);
,
down: async (queryInterface) =>
await queryInterface.bulkDelete("videos", null, );
await queryInterface.bulkDelete("courses", null, );
,
;
【讨论】:
注意: returning: true
选项是 only available for POSTGRES。如果您使用不同的方言/数据库,则会被忽略【参考方案3】:
bulkInsert
方法返回一个用第一个插入项的 ID 解析的承诺。我们可以使用这些信息来插入视频。它可能看起来像这样:
function getId( firstId, items, needly )
for ( let i = 0; i < items.length; i++ )
if ( items[i].title === needly )
return firstId + i;
return null;
exports.up = async ( queryInterface, Sequelize ) =>
const courses = [
title: 'Course 1',
description: '...',
,
title: 'Course 2',
description: '...',
,
title: 'Course 3',
description: '...',
,
title: 'Course 4',
description: '...',
,
title: 'Course 5',
description: '...',
,
];
const firstId = await queryInterface.bulkInsert( 'courses', courses, );
const course2Id = getId( firstId, courses, 'Course 2' );
const course5Id = getId( firstId, courses, 'Course 5' );
return queryInterface.bulkInsert( 'categories', [
title: 'Video 1', description: '...', courseId: course2Id ,
title: 'Video 2', description: '...', courseId: course2Id ,
title: 'Video 3', description: '...', courseId: course5Id ,
title: 'Video 4', description: '...', courseId: course5Id ,
title: 'Video 5', description: '...', courseId: course5Id ,
], );
;
exports.down = async ( queryInterface ) =>
await queryInterface.bulkDelete( 'videos', null, );
await queryInterface.bulkDelete( 'courses', null, );
【讨论】:
应该提到这种技术只适用于递增的整数 ID,但很高兴知道 bulkInsert 将解析为第一个插入的 ID。以上是关于Sequelize:带有关联的种子的主要内容,如果未能解决你的问题,请参考以下文章