Sequelize - 如何使用 sequelize 将 csv 数据插入 mysql 中的多个表
Sequelize - How to insert csv data into multiple tables in mysql using sequelize
我在用什么
node.js, express, sequelize 6.3.3, fast-csv 4.3.1 and mysql database.
我有什么
我有一个包含以下 headers 和数据的 CSV 文件。
no, name, email, township, father_name, father_phone, mother_name, mother_phone, parent_township
在这个 CSV 中,我有两种类型的数据:students
和 parents
。
在我的 MySQL
数据库中,我有三个 table:
students, parents and townships
同学们table:
id, name, email, township_id
Parents table:
id, student_id, father_name, father_phone, mother_name, mother_phone, parent_township_id
乡镇table:
id, name
我做了什么
我用 fast-csv
npm 包读取 CSV,代码如下。
let csvData = [];
fs.createReadStream(req.file.path)
.pipe(
csv.parse({
ignoreEmpty: true,
trim: true,
skipLines: 6,
})
)
.on("error", (error) => console.error(error))
.on("data", (row) => {
csvData.push(getHeaders(_.compact(row), csvStudentDataEntryFields));
})
.on("end", () => {
fs.unlinkSync(req.file.path);
const data = csvData.map((data) => {
const student = _.pick(data, studentFields);
const parent = _.pick(data, parentFields);
return [student, parent];
});
return res.status(201).send({
status: "success",
data,
});
});
我得到了什么
通过上面的代码,我得到了 data
以下值。
[
[ // row 1 from CSV
{
"name": "John",
"email": "john@gmail.com",
"township": "NYC",
},
{
"fatherName": "Smith",
"fatherPhone": "9111111111",
"motherName": "Mary",
"motherPhone": "9111111111",
"parentTownship": "NYC"
}
],
[ // row 2 from CSV
{
"name": "Cutter",
"email": "cutter@gmail.com",
"township": "NYC",
},
{
"fatherName": "Laseli",
"fatherPhone": "9111111111",
"motherName": "Mary",
"motherPhone": "9111111111",
"parentTownship": "NYC"
}
]
]
我想要的
我想将 data
中的 row 1
和 row 2
存储到数据库中相应的 table 中。
问题
我想我需要用真实 ID 替换那些 township
文本数据 因为我有如上所述的外键。
如何实现?我想在数据库级别进行。我不想在单独的 js 模块中查找那个乡镇名称的 id
。
已更新
学生模型
class Student extends Model {
static associate(models) {
Student.belongsTo(models.Township, {
foreignKey: "townshipId",
as: "township",
targetKey: "townshipId",
});
Student.hasOne(models.Parent, {
foreignKey: "studentId",
as: "parent",
sourceKey: "studentId",
});
}
}
Parent型号
class Parent extends Model {
static associate(models) {
Parent.belongsTo(models.Student, {
foreignKey: "studentId",
as: "student",
targetKey: "studentId",
});
Parent.belongsTo(models.Township, {
foreignKey: "parentTownshipId",
as: "township",
targetKey: "townshipId",
});
}
}
乡镇模式
class Township extends Model {
static associate(models) {
Township.hasMany(models.Student, {
foreignKey: "townshipId",
as: "township",
sourceKey: "townshipId",
});
Township.hasMany(models.Parent, {
foreignKey: "townshipId",
as: "parentTownship",
sourceKey: "townshipId",
});
}
}
更新:
在我的控制器中,
let std = await models.Student.create(
{
nameEn: "John",
email: "john@gmail.com",
townshipId: 1,
parent: [{ ...d[1], parentTownshipId: 1 }],
},
{ include: ["parent"] }
);
我想你可以把所有的关系都插入在一起。
这来自续集文档
const amidala = await User.create({
username: 'p4dm3',
points: 1000,
profiles: [{
name: 'Queen',
User_Profile: {
selfGranted: true
}
}]
}, {
include: Profile
});
const result = await User.findOne({
where: { username: 'p4dm3' },
include: Profile
});
console.log(result);
设置源密钥
const Foo = sequelize.define('foo', {
name: { type: DataTypes.TEXT, unique: true }
}, { timestamps: false });
const Bar = sequelize.define('bar', {
title: { type: DataTypes.TEXT, unique: true }
}, { timestamps: false });
const Baz = sequelize.define('baz', { summary: DataTypes.TEXT }, { timestamps: false });
Foo.hasOne(Bar, { sourceKey: 'name', foreignKey: 'fooName' });
Bar.hasMany(Baz, { sourceKey: 'title', foreignKey: 'barTitle' });
// [...]
await Bar.setFoo("Foo's Name Here");
await Baz.addBar("Bar's Title Here");
我在用什么
node.js, express, sequelize 6.3.3, fast-csv 4.3.1 and mysql database.
我有什么
我有一个包含以下 headers 和数据的 CSV 文件。
no, name, email, township, father_name, father_phone, mother_name, mother_phone, parent_township
在这个 CSV 中,我有两种类型的数据:students
和 parents
。
在我的 MySQL
数据库中,我有三个 table:
students, parents and townships
同学们table:
id, name, email, township_id
Parents table:
id, student_id, father_name, father_phone, mother_name, mother_phone, parent_township_id
乡镇table:
id, name
我做了什么
我用 fast-csv
npm 包读取 CSV,代码如下。
let csvData = [];
fs.createReadStream(req.file.path)
.pipe(
csv.parse({
ignoreEmpty: true,
trim: true,
skipLines: 6,
})
)
.on("error", (error) => console.error(error))
.on("data", (row) => {
csvData.push(getHeaders(_.compact(row), csvStudentDataEntryFields));
})
.on("end", () => {
fs.unlinkSync(req.file.path);
const data = csvData.map((data) => {
const student = _.pick(data, studentFields);
const parent = _.pick(data, parentFields);
return [student, parent];
});
return res.status(201).send({
status: "success",
data,
});
});
我得到了什么
通过上面的代码,我得到了 data
以下值。
[
[ // row 1 from CSV
{
"name": "John",
"email": "john@gmail.com",
"township": "NYC",
},
{
"fatherName": "Smith",
"fatherPhone": "9111111111",
"motherName": "Mary",
"motherPhone": "9111111111",
"parentTownship": "NYC"
}
],
[ // row 2 from CSV
{
"name": "Cutter",
"email": "cutter@gmail.com",
"township": "NYC",
},
{
"fatherName": "Laseli",
"fatherPhone": "9111111111",
"motherName": "Mary",
"motherPhone": "9111111111",
"parentTownship": "NYC"
}
]
]
我想要的
我想将 data
中的 row 1
和 row 2
存储到数据库中相应的 table 中。
问题
我想我需要用真实 ID 替换那些 township
文本数据 因为我有如上所述的外键。
如何实现?我想在数据库级别进行。我不想在单独的 js 模块中查找那个乡镇名称的 id
。
已更新
学生模型
class Student extends Model {
static associate(models) {
Student.belongsTo(models.Township, {
foreignKey: "townshipId",
as: "township",
targetKey: "townshipId",
});
Student.hasOne(models.Parent, {
foreignKey: "studentId",
as: "parent",
sourceKey: "studentId",
});
}
}
Parent型号
class Parent extends Model {
static associate(models) {
Parent.belongsTo(models.Student, {
foreignKey: "studentId",
as: "student",
targetKey: "studentId",
});
Parent.belongsTo(models.Township, {
foreignKey: "parentTownshipId",
as: "township",
targetKey: "townshipId",
});
}
}
乡镇模式
class Township extends Model {
static associate(models) {
Township.hasMany(models.Student, {
foreignKey: "townshipId",
as: "township",
sourceKey: "townshipId",
});
Township.hasMany(models.Parent, {
foreignKey: "townshipId",
as: "parentTownship",
sourceKey: "townshipId",
});
}
}
更新:
在我的控制器中,
let std = await models.Student.create(
{
nameEn: "John",
email: "john@gmail.com",
townshipId: 1,
parent: [{ ...d[1], parentTownshipId: 1 }],
},
{ include: ["parent"] }
);
我想你可以把所有的关系都插入在一起。
这来自续集文档
const amidala = await User.create({
username: 'p4dm3',
points: 1000,
profiles: [{
name: 'Queen',
User_Profile: {
selfGranted: true
}
}]
}, {
include: Profile
});
const result = await User.findOne({
where: { username: 'p4dm3' },
include: Profile
});
console.log(result);
设置源密钥
const Foo = sequelize.define('foo', {
name: { type: DataTypes.TEXT, unique: true }
}, { timestamps: false });
const Bar = sequelize.define('bar', {
title: { type: DataTypes.TEXT, unique: true }
}, { timestamps: false });
const Baz = sequelize.define('baz', { summary: DataTypes.TEXT }, { timestamps: false });
Foo.hasOne(Bar, { sourceKey: 'name', foreignKey: 'fooName' });
Bar.hasMany(Baz, { sourceKey: 'title', foreignKey: 'barTitle' });
// [...]
await Bar.setFoo("Foo's Name Here");
await Baz.addBar("Bar's Title Here");