不要怂,就是干,撸起袖子干!

Commit d2f33830 by Mike Sadowski Committed by Sushant

feat(postgres): support returning attributes with bulkCreate (#11170)

1 parent f3b5f99b
......@@ -170,6 +170,32 @@ User.bulkCreate([
})
```
Insert several rows and return all columns (Postgres only):
```js
User.bulkCreate([
{ username: 'barfooz', isAdmin: true },
{ username: 'foo', isAdmin: true },
{ username: 'bar', isAdmin: false }
], { returning: true }) // will return all columns for each row inserted
.then((result) => {
console.log(result);
});
```
Insert several rows and return specific columns (Postgres only):
```js
User.bulkCreate([
{ username: 'barfooz', isAdmin: true },
{ username: 'foo', isAdmin: true },
{ username: 'bar', isAdmin: false }
], { returning: ['username'] }) // will return only the specified columns for each row inserted
.then((result) => {
console.log(result);
});
```
To update several rows at once:
```js
......
......@@ -313,8 +313,15 @@ class QueryGenerator {
const ignoreDuplicates = options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : '';
const attributes = allAttributes.map(attr => this.quoteIdentifier(attr)).join(',');
const returning = this._dialect.supports.returnValues && options.returning ? ' RETURNING *' : '';
const onConflictDoNothing = options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : '';
let returning = '';
if (this._dialect.supports.returnValues && Array.isArray(options.returning)) {
const fields = options.returning.map(field => this.quoteIdentifier(field)).join(',');
returning += ` RETURNING ${fields}`;
} else {
returning += this._dialect.supports.returnValues && options.returning ? ' RETURNING *' : '';
}
return `INSERT${ignoreDuplicates} INTO ${this.quoteTable(tableName)} (${attributes}) VALUES ${tuples.join(',')}${onDuplicateKeyUpdate}${onConflictDoNothing}${returning};`;
}
......
......@@ -2522,7 +2522,7 @@ class Model {
* @param {Transaction} [options.transaction] Transaction to run query under
* @param {Function} [options.logging=false] A function that gets executed while running the query to log the sql.
* @param {boolean} [options.benchmark=false] Pass query execution time in milliseconds as second argument to logging function (options.logging).
* @param {boolean} [options.returning=false] Append RETURNING * to get back auto generated values (Postgres only)
* @param {boolean|Array} [options.returning=false] If true, append RETURNING * to get back all values; if an array of column names, append RETURNING <columns> to get back specific columns (Postgres only)
* @param {string} [options.searchPath=DEFAULT] An optional parameter to specify the schema search_path (Postgres only)
*
* @returns {Promise<Array<Model>>}
......@@ -2652,6 +2652,11 @@ class Model {
}
}
// Map returning attributes to fields
if (options.returning && Array.isArray(options.returning)) {
options.returning = options.returning.map(attr => this.rawAttributes[attr].field || attr);
}
return this.QueryInterface.bulkInsert(this.getTableName(options), records, options, fieldMappedAttributes).then(results => {
if (Array.isArray(results)) {
results.forEach((result, i) => {
......
......@@ -819,6 +819,9 @@ if (dialect.startsWith('postgres')) {
arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { returning: true }],
expectation: "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'),('bar') RETURNING *;"
}, {
arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { returning: ['id', 'sentToId'] }],
expectation: "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'),('bar') RETURNING \"id\",\"sentToId\";"
}, {
arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true, returning: true }],
expectation: "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'),('bar') ON CONFLICT DO NOTHING RETURNING *;"
}, {
......
......@@ -741,9 +741,9 @@ export interface BulkCreateOptions extends Logging, Transactionable {
updateOnDuplicate?: string[];
/**
* Return the affected rows (only for postgres)
* Return all columns or only the specified columns for the affected rows (only for postgres)
*/
returning?: boolean;
returning?: boolean | string[];
}
/**
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!