我正在使用“ pg”(node-postgres)在带有Node app的Postgres DB上执行一些基本的CRUD操作。进行此特定查询时似乎有些问题-整个应用程序挂起,就像Promise永远无法解决一样。执行将在此时停止,并且不会引发错误。
在我稍稍更改数据库结构并重构代码(使其更具模块化等)之前,整个工作正常。数据库已建立并连接(使用Cloud9的Ubuntu 14.04 LTS容器),其他查询成功检查了该数据库是否存在。 失败的查询(“从清单中选择*”)通常可以正常工作-在psql CLI中键入该查询时,应得到0行的结果。因此,我最好的猜测是,异步/等待逻辑中的某些内容不正确。
// This part executes without issues
const initDB = async () => {
try {
await client.connect();
console.log('Client connected to db ...');
const checkTable = await client.query("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'inventory')");
if (!checkTable.rows[0].exists) {
const table = await client.query('CREATE TABLE inventory (prod_id serial PRIMARY KEY, product_name VARCHAR (50), category TEXT, description TEXT, price REAL, width INT, depth INT, height INT, checksum TEXT, history REAL ARRAY)');
}
} catch (err) {
console.log("Error initializing db.", err);
}
};
// This part fails
Promise.all([getProductData(productsUrlBase)]).then(async (values) => {
// checksum = ...
try {
console.log('This logs on the console');
const check = await client.query('SELECT * FROM inventory WHERE checksum=$1', [checksum]);
console.log(check.rows, 'if this is empty, INSERT in DB!'); // Never logs on the console. App doesn't throw error, either.
} catch (err) {
console.log('Query error - checking / inserting items: ', err);
}
});
Postgres log file:
2019-04-19 12:18:53 UTC LOG: database system was interrupted; last known up at 2019-04-19 08:39:56 UTC
2019-04-19 12:18:54 UTC LOG: database system was not properly shut down; automatic recovery in progress
2019-04-19 12:18:54 UTC LOG: record with zero length at 0/17A3BF8
2019-04-19 12:18:54 UTC LOG: redo is not required
2019-04-19 12:18:54 UTC LOG: MultiXact member wraparound protections are now enabled
2019-04-19 12:18:54 UTC LOG: database system is ready to accept connections
2019-04-19 12:18:54 UTC LOG: autovacuum launcher started
2019-04-19 12:18:54 UTC LOG: incomplete startup packet
我希望至少得到Error,但是什么也没发生。您可以看到Postgres服务器日志-在我看来,那里似乎没有任何重大问题。
这是完整的GitHub回购。问题部分在./data-handlers/update.js
答案 0 :(得分:1)
您的代码中有一些小问题,但除此之外,做得很好。
1)正确返回或等待承诺:
-https://github.com/kboeff/price-checker/blob/master/app.js#L63
和
-https://github.com/kboeff/price-checker/blob/master/data-handlers/update.js#L12
2)通过await client.connect()
连接node-postgres,再次阅读文档是值得的
3)错误的循环=> https://github.com/kboeff/price-checker/blob/master/data-handlers/update.js#L18
4),该部分仍位于for循环内,该循环旨在遍历对象属性,但应位于“针对每个记录”循环https://github.com/kboeff/price-checker/blob/master/data-handlers/update.js#L28-L53
中 5)查询$9
https://github.com/kboeff/price-checker/blob/master/data-handlers/update.js#L36
您确定要一次触发所有这些查询吗?也许同步会更好。在谈论性能时,也许您应该将postgres类型的UUID用于校验和操作。
这是一个使用md5作为校验和的工作示例:
const { Client } = require('pg');
const priceAlert = require('./price-alert');
const getProductData = require('./get-product-data');
const crypto = require('crypto');
const client = new Client;
const updateDB = async (productsUrlBase, category) => {
// connect to db
await client.connect();
const records = await getProductData(productsUrlBase);
for (const record of records) {
let checksum = '';
for (let key in record){
if (record.hasOwnProperty(key)) {
if (key !== 'price') {
checksum += record[key] || '';
}
}
}
try {
const md5Checksum = crypto.createHash('md5').update(checksum).digest("hex");
const check = await client.query('SELECT * FROM inventory WHERE checksum=$1', [md5Checksum]);
console.log(check, 'if this is empty, INSERT in DB!'); // DEBUG
// Record not found in db, add.
let arrLit = '{' + record.price +'}';
if (check.rows.length === 0) {
let rows = await client.query("INSERT INTO inventory(product_name, category, description, price, width, depth, height, checksum, history) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", [record.name, category, record.description, record.price, record.width, record.depth, record.height, md5Checksum, arrLit]);
console.log(rows, 'INSERTED to DB.'); // DEBUG
} else {
// compare prices, signal for changes!
let item = check.rows[0];
// console.log(item);
if (item.price !== record.price) {
priceAlert(item, record.price);
let formattedPrice = parseFloat(Math.round(record.price * 100) / 100).toFixed(2);
let txt = "UPDATE inventory SET price=" + formattedPrice + ", history = history||ARRAY[cast(" + formattedPrice +"as real)] WHERE checksum='" + checksum + "::uuid'";
let updatePrice = await client.query(txt);
console.log(updatePrice);
}
}
} catch (err) {
console.log('Query error - checking / inserting items: ', typeof record.price, err);
}
}
};
module.exports = updateDB;
此示例的列清单.checksum必须为UUID类型
alter table inventory add column checksum uuid;
PS:例如,也许还会在app.js第64行添加process.exit();