作法:使用pg-promise顺序db.batch

时间:2018-11-04 16:04:58

标签: node.js pg-promise

我无法弄清楚如何顺序执行所生成查询的批处理调用。

我试图截断数据库中的每个表。我的代码:

db.any(`
  SELECT table_name
  FROM information_schema.tables
  WHERE table_schema='public'
  AND table_type='BASE TABLE';
`)
.then(res => res.map(item => item.table_name)) // To get only an array with the names
.then(tables => tables.map(tableName => db.none(`TRUNCATE TABLE ${tableName} CASCADE`))) // ES6 template strings, because the table name must be bare here (no quotes)
.then(queries => db.tx(t => t.batch(queries)))

我发现死锁错误。很明显,为什么会出现僵局:查询级联,并尝试截断与另一个查询相同的表。这就是为什么我需要同步调用查询的原因。我不知道该怎么做。我尝试使用db.sequence(),但遇到了同样的错误。用pg-promise顺序执行生成的查询的正确方法是什么?非常感谢。

1 个答案:

答案 0 :(得分:1)

pg-promise支持的语法非常灵活。下面仅是一种这样的语法,它最适合您的情况,也是最现代的一种:

db.tx(async t => {
    const tables = await t.map(`
        SELECT table_name
        FROM information_schema.tables
        WHERE table_schema = $1
        AND table_type = $2
    `, ['public', 'BASE TABLE'], a => a.table_name);

    for (let i = 0; i < tables.length; i++) {
        await t.none('TRUNCATE TABLE $1:name CASCADE', tables[i]);
    }
});
  

// ES6模板字符串,因为表名必须在此处裸露(不带引号)

这是错误的,名称必须用双引号引起来,我们使用SQL Names过滤器提供了该功能。

也请参见here

  

切勿在ES6模板字符串中使用保留的$ {}语法,因为它们不知道如何格式化PostgreSQL的值。