私はPostgreSQLにupsertクエリがあります:
INSERT INTO table
(id, name)
values
(1, 'Gabbar')
ON CONFLICT (id) DO UPDATE SET
name = 'Gabbar'
WHERE
table.id = 1
このアップサートクエリにknexを使用する必要があります。これについてどうやって行くの?
だから私は次の提案を使ってこれを解決しました Knexの問題のページでのDotnilの回答 :
var data = {id: 1, name: 'Gabbar'};
var insert = knex('table').insert(data);
var dataClone = _.cloneDeep(data);
delete dataClone.id;
var update = knex('table').update(dataClone).whereRaw('table.id = ' + data.id);
var query = util.format('%s ON CONFLICT (id) DO UPDATE SET %s',
insert.toString(),
update.toString().replace(/^update\s.*\sset\s/i, '')
);
return knex.raw(query)
.then(function(dbRes){
// stuff
});
これが誰かを助けることを願っています。
私が考えることができるさらに別のアプローチ!
exports.upsert = (t, tableName, columnsToRetain, conflictOn) => {
const insert = knex(tableName)
.insert(t)
.toString();
const update = knex(tableName)
.update(t)
.toString();
const keepValues = columnsToRetain.map((c) => `"${c}"=${tableName}."${c}"`).join(',');
const conflictColumns = conflictOn.map((c) => `"${c.toString()}"`).join(',');
let insertOrUpdateQuery = `${insert} ON CONFLICT( ${conflictColumns}) DO ${update}`;
insertOrUpdateQuery = keepValues ? `${insertOrUpdateQuery}, ${keepValues}` : insertOrUpdateQuery;
insertOrUpdateQuery = insertOrUpdateQuery.replace(`update "${tableName}"`, 'update');
insertOrUpdateQuery = insertOrUpdateQuery.replace(`"${tableName}"`, tableName);
return Promise.resolve(knex.raw(insertOrUpdateQuery));
};
私はこれを行うための関数を作成しました knex githubの問題のページで説明されています (複合固有のインデックスを処理するための落とし穴とともに)。