如何使用 node-postgres 将多行正确插入 PG?
How do I properly insert multiple rows into PG with node-postgres?
单行可以这样插入:
client.query("insert into tableName (name, email) values (, ) ", ['john', 'john@gmail.com'], callBack)
这种方法会自动注释掉任何特殊字符。
如何一次插入多行?
我需要实现这个:
"insert into tableName (name, email) values ('john', 'john@gmail.com'), ('jane', 'jane@gmail.com')"
我可以只使用 js 字符串运算符手动编译这些行,但是我需要以某种方式添加特殊字符转义。
client.query("insert into tableName (name, email) values (, ),(, ) ", ['john', 'john@gmail.com','john', 'john@gmail.com'], callBack)
没有帮助?
更进一步,您可以手动生成一个字符串进行查询:
insert into tableName (name, email) values (" +var1 + "," + var2 + "),(" +var3 + ", " +var4+ ") "
如果您阅读此处,https://github.com/brianc/node-postgres/issues/530,您可以看到相同的实现。
关注这篇文章:Performance Boost from pg-promise 库及其建议的方法:
// Concatenates an array of objects or arrays of values, according to the template,
// to use with insert queries. Can be used either as a class type or as a function.
//
// template = formatting template string
// data = array of either objects or arrays of values
function Inserts(template, data) {
if (!(this instanceof Inserts)) {
return new Inserts(template, data);
}
this._rawDBType = true;
this.formatDBType = function () {
return data.map(d=>'(' + pgp.as.format(template, d) + ')').join(',');
};
}
使用它的示例,与您的情况完全相同:
var users = [['John', 23], ['Mike', 30], ['David', 18]];
db.none('INSERT INTO Users(name, age) VALUES ', Inserts(', ', users))
.then(data=> {
// OK, all records have been inserted
})
.catch(error=> {
// Error, no records inserted
});
它也适用于一组对象:
var users = [{name: 'John', age: 23}, {name: 'Mike', age: 30}, {name: 'David', age: 18}];
db.none('INSERT INTO Users(name, age) VALUES ', Inserts('${name}, ${age}', users))
.then(data=> {
// OK, all records have been inserted
})
.catch(error=> {
// Error, no records inserted
});
UPDATE-1
对于通过单个 INSERT
查询的 high-performance 方法,请参阅 。
UPDATE-2
这里的信息现在已经很旧了,请参阅 Custom Type Formatting 的最新语法。以前的_rawDBType
现在是rawType
,formatDBType
改名为toPostgres
.
另一种使用 PostgreSQL json 函数的方法:
client.query('INSERT INTO table (columns) ' +
'SELECT m.* FROM json_populate_recordset(null::your_custom_type, ) AS m',
[JSON.stringify(your_json_object_array)], function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
像下面那样使用pg-format。
var format = require('pg-format');
var values = [
[7, 'john22', 'john22@gmail.com', '9999999922'],
[6, 'testvk', 'testvk@gmail.com', '88888888888']
];
client.query(format('INSERT INTO users (id, name, email, phone) VALUES %L', values),[], (err, result)=>{
console.log(err);
console.log(result);
});
您将不得不动态生成查询。虽然可能,但这是有风险的,如果你做错了,很容易导致 SQL 注入漏洞。查询中的参数索引和您传递的参数之间的差一个错误也很容易结束。
话虽这么说,这里是一个如何编写此示例的示例,假设您有一组看起来像 {name: string, email: string}
:
的用户
client.query(
`INSERT INTO table_name (name, email) VALUES ${users.map(() => `(?, ?)`).join(',')}`,
users.reduce((params, u) => params.concat([u.name, u.email]), []),
callBack,
)
另一种方法是使用像 @databases/pg
(我写的)这样的库:
await db.query(sql`
INSERT INTO table_name (name, email)
VALUES ${sql.join(users.map(u => sql`(${u.name}, ${u.email})`), ',')}
`)
@databases 要求用 sql
标记查询,并使用它来确保您传递的任何用户数据始终自动转义。这也让您可以内联编写参数,我认为这使代码更具可读性。
使用以标记模板字符串为核心的 npm 模块 postgres (porsager/postgres):
https://github.com/porsager/postgres#multiple-inserts-in-one-query
const users = [{
name: 'Murray',
age: 68,
garbage: 'ignore'
},
{
name: 'Walter',
age: 80,
garbage: 'ignore'
}]
sql`insert into users ${ sql(users, 'name', 'age') }`
// Is translated to:
insert into users ("name", "age") values (, ), (, )
// Here you can also omit column names which will use all object keys as columns
sql`insert into users ${ sql(users) }`
// Which results in:
insert into users ("name", "age", "garbage") values (, , ), (, , )
我只是想 post,因为它就像刚结束测试的全新版本,而且我发现它是 SQL 库的更好理念。我认为比其他 postgres/node 图书馆 posted 在其他答案中更可取。恕我直言
嗨,我知道我来晚了,但对我有用的是一张简单的地图。
我希望这能帮助寻求相同的人
let sampleQuery = array.map(myRow =>
`('${myRow.column_a}','${myRow.column_b}') `
)
let res = await pool.query(`INSERT INTO public.table(column_a, column_b) VALUES ${sampleQuery} `)
单行可以这样插入:
client.query("insert into tableName (name, email) values (, ) ", ['john', 'john@gmail.com'], callBack)
这种方法会自动注释掉任何特殊字符。
如何一次插入多行?
我需要实现这个:
"insert into tableName (name, email) values ('john', 'john@gmail.com'), ('jane', 'jane@gmail.com')"
我可以只使用 js 字符串运算符手动编译这些行,但是我需要以某种方式添加特殊字符转义。
client.query("insert into tableName (name, email) values (, ),(, ) ", ['john', 'john@gmail.com','john', 'john@gmail.com'], callBack)
没有帮助? 更进一步,您可以手动生成一个字符串进行查询:
insert into tableName (name, email) values (" +var1 + "," + var2 + "),(" +var3 + ", " +var4+ ") "
如果您阅读此处,https://github.com/brianc/node-postgres/issues/530,您可以看到相同的实现。
关注这篇文章:Performance Boost from pg-promise 库及其建议的方法:
// Concatenates an array of objects or arrays of values, according to the template,
// to use with insert queries. Can be used either as a class type or as a function.
//
// template = formatting template string
// data = array of either objects or arrays of values
function Inserts(template, data) {
if (!(this instanceof Inserts)) {
return new Inserts(template, data);
}
this._rawDBType = true;
this.formatDBType = function () {
return data.map(d=>'(' + pgp.as.format(template, d) + ')').join(',');
};
}
使用它的示例,与您的情况完全相同:
var users = [['John', 23], ['Mike', 30], ['David', 18]];
db.none('INSERT INTO Users(name, age) VALUES ', Inserts(', ', users))
.then(data=> {
// OK, all records have been inserted
})
.catch(error=> {
// Error, no records inserted
});
它也适用于一组对象:
var users = [{name: 'John', age: 23}, {name: 'Mike', age: 30}, {name: 'David', age: 18}];
db.none('INSERT INTO Users(name, age) VALUES ', Inserts('${name}, ${age}', users))
.then(data=> {
// OK, all records have been inserted
})
.catch(error=> {
// Error, no records inserted
});
UPDATE-1
对于通过单个 INSERT
查询的 high-performance 方法,请参阅
UPDATE-2
这里的信息现在已经很旧了,请参阅 Custom Type Formatting 的最新语法。以前的_rawDBType
现在是rawType
,formatDBType
改名为toPostgres
.
另一种使用 PostgreSQL json 函数的方法:
client.query('INSERT INTO table (columns) ' +
'SELECT m.* FROM json_populate_recordset(null::your_custom_type, ) AS m',
[JSON.stringify(your_json_object_array)], function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
像下面那样使用pg-format。
var format = require('pg-format');
var values = [
[7, 'john22', 'john22@gmail.com', '9999999922'],
[6, 'testvk', 'testvk@gmail.com', '88888888888']
];
client.query(format('INSERT INTO users (id, name, email, phone) VALUES %L', values),[], (err, result)=>{
console.log(err);
console.log(result);
});
您将不得不动态生成查询。虽然可能,但这是有风险的,如果你做错了,很容易导致 SQL 注入漏洞。查询中的参数索引和您传递的参数之间的差一个错误也很容易结束。
话虽这么说,这里是一个如何编写此示例的示例,假设您有一组看起来像 {name: string, email: string}
:
client.query(
`INSERT INTO table_name (name, email) VALUES ${users.map(() => `(?, ?)`).join(',')}`,
users.reduce((params, u) => params.concat([u.name, u.email]), []),
callBack,
)
另一种方法是使用像 @databases/pg
(我写的)这样的库:
await db.query(sql`
INSERT INTO table_name (name, email)
VALUES ${sql.join(users.map(u => sql`(${u.name}, ${u.email})`), ',')}
`)
@databases 要求用 sql
标记查询,并使用它来确保您传递的任何用户数据始终自动转义。这也让您可以内联编写参数,我认为这使代码更具可读性。
使用以标记模板字符串为核心的 npm 模块 postgres (porsager/postgres):
https://github.com/porsager/postgres#multiple-inserts-in-one-query
const users = [{
name: 'Murray',
age: 68,
garbage: 'ignore'
},
{
name: 'Walter',
age: 80,
garbage: 'ignore'
}]
sql`insert into users ${ sql(users, 'name', 'age') }`
// Is translated to:
insert into users ("name", "age") values (, ), (, )
// Here you can also omit column names which will use all object keys as columns
sql`insert into users ${ sql(users) }`
// Which results in:
insert into users ("name", "age", "garbage") values (, , ), (, , )
我只是想 post,因为它就像刚结束测试的全新版本,而且我发现它是 SQL 库的更好理念。我认为比其他 postgres/node 图书馆 posted 在其他答案中更可取。恕我直言
嗨,我知道我来晚了,但对我有用的是一张简单的地图。
我希望这能帮助寻求相同的人
let sampleQuery = array.map(myRow =>
`('${myRow.column_a}','${myRow.column_b}') `
)
let res = await pool.query(`INSERT INTO public.table(column_a, column_b) VALUES ${sampleQuery} `)