Sequelize新手求助:如何根据country_iso2关联插入数据到contact表
问题描述
我是Sequelize新手,已创建两张表:
contact表:字段为id、name、nationalNumber、countryIdcountries表:字段为id、iso2
API接收的数组数据格式如下:
[ { "name": "Aftab", "mobile_number": "3408906107", "name_check": 0, "country_iso2": "PK" }, { "name": "Numan Jhanger", "mobile_number": "3179608039", "name_check": "0", "country_iso2": "PK" }, { "name": "Muhammad Zaki", "mobile_number": "3175623123", "name_check": 0, "country_iso2": "PK" }, { "name": "Irshad Khan", "mobile_number": "3428890654", "name_check": 0, "country_iso2": "PK" } ]
需求是根据每条数据的country_iso2从countries表获取对应的id,再将数据插入contact表。现有代码中country_id写死为167,需要替换为动态获取的ID:
async function create(data) { return new Promise(async (resolve, reject) => { data.contacts.map(async (item, index) => { let ios2 = item.country_iso2; delete item.country_iso2; await db.filtered_contacts .findOrCreate({ where: { mobile_number: item.mobile_number }, defaults: { ...item, country_id: 167 }, }) .then(([item, created]) => { console.log(item); // John console.log(created); // true }); }); resolve("dsds"); }); }
已正确定义表关联关系:
// countries and filter contact relations db.countries.hasMany(db.filtered_contacts, { foreignKey: "country_id", }); db.filtered_contacts.belongsTo(db.countries, { foreignKey: "country_id", });
需要指导如何实现根据country_iso2获取countryId并完成插入。
解决方案
1. 核心修改思路
- 先通过
country_iso2查询对应国家的ID - 修正原代码中异步逻辑的缺陷(
map+async无法正确等待、外层Promise冗余) - 处理数据类型统一、异常情况(如未找到对应国家)
2. 基础版本代码
async function create(data) { try { // 用Promise.all等待所有异步操作完成,避免提前resolve await Promise.all(data.contacts.map(async (item) => { // 解构拆分字段,分离出需要处理的国家编码 const { country_iso2, mobile_number, ...rest } = item; // 根据iso2查询对应国家的ID,只获取需要的字段提升性能 const country = await db.countries.findOne({ where: { iso2: country_iso2 }, attributes: ['id'] }); // 处理未找到国家的情况,避免无效插入 if (!country) { console.warn(`未找到iso2为${country_iso2}的国家记录,跳过该联系人`); return; } // 统一name_check的类型(原数据存在数字/字符串混合的情况) const normalizedData = { ...rest, mobile_number, name_check: Number(rest.name_check), country_id: country.id }; // 执行findOrCreate操作 const [contact, created] = await db.filtered_contacts.findOrCreate({ where: { mobile_number }, defaults: normalizedData }); console.log(`联系人${contact.name} ${created ? '已创建' : '已存在'}`); })); return '所有联系人处理完成'; } catch (error) { console.error('处理联系人时出错:', error); throw error; // 抛出错误让调用方处理 } }
3. 大数据量优化版本
如果需要处理的联系人数据较多,每条单独查询国家会产生大量数据库请求,建议先批量查询所有涉及的国家,再通过映射表匹配ID:
async function create(data) { try { // 收集所有唯一的国家编码,避免重复查询 const uniqueIso2s = [...new Set(data.contacts.map(item => item.country_iso2))]; // 批量查询所有涉及的国家 const countries = await db.countries.findAll({ where: { iso2: uniqueIso2s }, attributes: ['id', 'iso2'] }); // 构建iso2到id的映射表 const iso2ToIdMap = {}; countries.forEach(country => { iso2ToIdMap[country.iso2] = country.id; }); // 批量处理联系人数据 await Promise.all(data.contacts.map(async (item) => { const { country_iso2, mobile_number, ...rest } = item; const countryId = iso2ToIdMap[country_iso2]; if (!countryId) { console.warn(`未找到iso2为${country_iso2}的国家记录,跳过该联系人`); return; } const normalizedData = { ...rest, mobile_number, name_check: Number(rest.name_check), country_id: countryId }; const [contact, created] = await db.filtered_contacts.findOrCreate({ where: { mobile_number }, defaults: normalizedData }); console.log(`联系人${contact.name} ${created ? '已创建' : '已存在'}`); })); return '所有联系人处理完成'; } catch (error) { console.error('处理联系人时出错:', error); throw error; } }
内容的提问来源于stack exchange,提问作者Engr.Aftab Ufaq
相关产品推荐
相关产品推荐

