省略列名/将对象直接插入 node-postgres

Omiting column names / inserting objects directly into node-postgres

我想将列名作为 keys 的字典传递,从而避免在查询本身中声明列名(直接输入它们)。


假设我有一个 table User 和 2 个列名:

要使用 node-postgres 创建记录,我需要 在查询中声明 列名称,如下所示:

    var idUser   = 2;
    var fullName = "John Doe";
    var query = 'INSERT INTO User(idUser, age) VALUES (, )';

    database.query(query, [idUser, fullName], function(error, result) {
      callback(error, result.rows);
      database.end();
    });

如果有一种方法可以只传递字典并让它从键中推断出列名,我更愿意 - 如果有一个简单的技巧,我想听听。

例如:

    var values = {
      idUser  : 2,
      fullName: "John Doe"
    };
    var query = 'INSERT INTO User VALUES ()';

    database.query(query, [values], function(error, result) {
      callback(error, result.rows);
      database.end();
    });

insert 语句中不支持键值对值,因此无法使用原生 sql 完成。

但是,node-postgres extras page mentions multiple sql generation tools, and for example Squel.js 参数可用于构造 sql,其方式与您正在寻找的非常接近:

squel.insert()
    .into("User")
    .setFieldsRows([
      { idUser: 2, fullName: "John Doe" }
    ])
    .toParam()

// => { text: 'INSERT INTO User (idUser, fullName) VALUES (?, ?)',
//      values: [ 2, 'John Doe' ] }

使用 pg-promise 完成的完整示例:

const pgp = require('pg-promise')(/*options*/);
const cn = 'postgres://username:password@host:port/database';
const db = pgp(cn);

const values = {
    idUser: 2,
    fullName: 'John Doe'
};

// generating the insert query:
const query = pgp.helpers.insert(values, null, 'User');
//=> INSERT INTO "User"("idUser","fullName") VALUES(2,'John Doe')

db.none(query)
    .then(data => {
        // success;
    })
    .catch(error => {
        // error;
    });

如果专注于高性能,它将更改为:

// generating a set of columns from the object (only once):
const cs = new pgp.helpers.ColumnSet(values, {table: 'User'});

// generating the insert query:
const query = pgp.helpers.insert(values, cs);
//=> INSERT INTO "User"("idUser","fullName") VALUES(2,'John Doe')