有没有办法在续集中进行批量upsert。另外,我可以指定用于检查重复的密钥。
我试过以下但没有奏效:
Employee.bulkCreate(data, {
updateOnDuplicate: true
});
批量创作工作正常。上面的语句总是在DB中创建新条目。
答案 0 :(得分:22)
来自官方Custom Headers。
可以使用updateOnDuplicate
选项Employee.bulkCreate(dataArray,
{
fields:["id", "name", "address"] ,
updateOnDuplicate: ["name"]
} )
来完成。
就像这样:
updateOnDuplicate
dataArray
是一个字段数组,当主键(或可能是唯一键)与行匹配时,这些字段将被更新。确保模型中至少有一个唯一字段(比方说id), btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
createWebPrintJob(webView);
} else {
}
}
});
中的唯一字段用于upsert。
答案 1 :(得分:3)
由于答案不支持PostgreSQL,因此使用Sequelize的““”“”最佳“”“”替代方法是使用ON CONFLICT
语句进行手动查询。示例(打字稿):
const values: Array<Array<number | string>> = [
[1, 'Apple', 'Red', 'Yummy'],
[2, 'Kiwi', 'Green', 'Yuck'],
]
const query = 'INSERT INTO fruits (id, name, color, flavor) VALUES ' +
values.map(_ => { return '(?)' }).join(',') +
' ON CONFLICT (id) DO UPDATE SET flavor = excluded.flavor;'
sequelize.query({ query, values }, { type: sequelize.QueryTypes.INSERT })
这将建立一个查询,例如:
INSERT INTO
fruits (id, name, color, flavor)
VALUES
(1, 'Apple', 'Red', 'Yummy'),
(2, 'Kiwi', 'Green', 'Yuck')
ON CONFLICT (id) DO UPDATE SET
flavor = excluded.flavor;
可以说,这不是必须手动构建查询的理想解决方案,因为它违反了使用序列化的目的,但是,如果您不需要的是一次性查询,则可以使用此方法。
答案 2 :(得分:1)
2019更新
适用于所有方言,只要满足特定的最低版本要求
HERE是对同一源代码的引用
请注意,个别选项可能适用于所有方言,也可能无法适用于所有方言 例如,updateOnDuplicate仅在MySQL,MariaDB, SQLite和Postgres
ignoreDuplicates选项在MSSQL上不起作用
还要在源代码中检查此代码块
if (Array.isArray(options.updateOnDuplicate) && options.updateOnDuplicate.length) {
options.updateOnDuplicate = _.intersection(
_.without(Object.keys(model.tableAttributes), createdAtAttr),
options.updateOnDuplicate
);
} else {
return Promise.reject(new Error('updateOnDuplicate option only supports non-empty array.'));
}
updateOnDuplicate必须是一个数组,不能为true或false
根据以上几点,您的代码应该是这样的
Employee.bulkCreate(data, {
updateOnDuplicate: ['employeeName', 'employeeAge'],
});
更新:
由于有人提到它不起作用,请尝试
models.Employee.bulkCreate(items, {
returning: ['employeeId'],
ignoreDuplicates: true
})
答案 3 :(得分:1)
2020年10月1日更新
续集版本:^ 6.3.5
问题仍然存在。我们仍然无法bulkUpsert
使用唯一的复合索引。 bulkCreate
和updateOnDuplicates
尚不适用于唯一的复合索引。还有PR正在等待合并,这可能会解决此问题:-
https://github.com/sequelize/sequelize/pull/12516
https://github.com/sequelize/sequelize/pull/12547
目前,如果有人想快速解决问题,则可以通过使用自己的表属性,名称和数据进行修改来使用以下基于原始查询的包装器:-
const bulkUpsertIntoTable = async ({ bulkUpsertableData }) => {
try {
/* eslint-disable */
// id column will automatically be incremented if you have set it to auto-increment
const query = `INSERT INTO "Table" ("non_id_attr1", "non_id_attr2", "non_id_attr3","createdAt", "updatedAt") VALUES ${bulkUpsertableData
.map((_) => "(?)")
.join(
","
)} ON CONFLICT ("non_id_attr1","non_id_attr2") DO UPDATE SET "non_id_attr1"=excluded."non_id_attr1", "non_id_attr2"=excluded."non_id_attr2", "non_id_attr3"=excluded."non_id_attr3", "updatedAt"=excluded."updatedAt" RETURNING "id","non_id_attr1","non_id_attr2","non_id_attr3","createdAt","updatedAt";`;
/* eslint-enable */
return await models.sequelize.query(query, {
replacements: bulkUpsertableData,//------> dont forget to pass your data here
type: models.Sequelize.QueryTypes.INSERT,
// transaction:t -----> if required to be done in transaction
});
} catch (error) {
console.error("Bulk Upserting into Table:", error);
throw error;
}
};
重要的一点是创建bulkUpsertableData
。创建示例:-
Array<Array> ie:- [[]]
答案 4 :(得分:0)
2020年11月2日更新
基于@Yedhin答案,这是一个更通用的解决方案(打字稿):
let url = URL(string: "http://192.168.1.318:8080")! /*localhost*/
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
request.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData
// or
request.cachePolicy = .reloadIgnoringCacheData