简体   繁体   中英

Getting undefined error from postgresql query in NodeJs

I'm trying to execute query and use some rows of the results.

When I tried this code:

const pg = require('pg')
var Log = require('fancy-log');
var jsonPath = require('jsonpath');
var validator = require('validator');
var isEmpty = require('is-empty-array')
const argv = require('yargs').argv
require('custom-env').env(argv.env)

var db = require('./db');
var checker = require('./checklist')

let txn_id;
var param = []

//////////////////////////////////// DB Connection Block & executeQuery ////////////////////////////////////

var config = {
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    database: process.env.DB,
    max: 10, // max number of clients in the pool
    idleTimeoutMillis: 30000 // how long a client is allowed to remain idle before being closed
}

const pool = new pg.Pool(config)

async function query(q,param) {
    const client = await pool.connect()
    let res
    try {
        await client.query('BEGIN')
        try {
            res = await client.query(q, param)
            await client.query('COMMIT')
            Log("Connection succeed.")
        } catch (err) {
            await client.query('ROLLBACK')
            throw err
        }
    } finally {
        client.release()
    }
    return res
}

//////////////////////////////////// DB Connection Block & executeQuery ////////////////////////////////////


//client.getConnection();

//db.main()
//db.print()

async function executeQuery(queryParam, conditions) {
    try {
        const { rows, rowCount } = await query(queryParam, conditions)
        txn_id = await rows[Math.floor(Math.random() * rowCount + 1)].txn_id
        Log("Related txn_id: " + txn_id)
    } catch (err) {
        console.log('Database ' + err)
    }
}


executeQuery("SELECT * from table_name",[])

I got this error all the time:

Database TypeError: Cannot read property 'txn_id' of undefined

My first usecase is working two different js file like db.js for connection and query function , export it and use it in main.js . Unfortunately, I couldn't get success. Probably, I don't understand fully of await usage.

Thanks for any idea in advance!

EDIT: This is main goal. I want to seperate all my logics.

db.js

const pg = require('pg')
var Log = require('fancy-log');
const argv = require('yargs').argv
require('custom-env').env(argv.env)

//var db = function(){};
let txn_id;
var param = []

var config = {
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    database: process.env.DB,
    max: 10, // max number of clients in the pool
    idleTimeoutMillis: 30000 // how long a client is allowed to remain idle before being closed
}

const pool = new pg.Pool(config)

async function query(q,param) {
    const client = await pool.connect()
    let res
    try {
        await client.query('BEGIN')
        try {
            res = await client.query(q, param)
            await client.query('COMMIT')
            Log("Connection succeed.")
        } catch (err) {
            await client.query('ROLLBACK')
            throw err
        }
    } finally {
        client.release()
    }
    return res
}

async function executeQuery(queryParam, conditions) {
    try {
        const { rows, rowCount } = await query(queryParam,conditions)
        txn_id = await rows[Math.floor(Math.random() * rowCount + 1)].txn_id
        Log("Related txn_id: " + txn_id)
    } catch (err) {
        console.log('Database ' + err)
    }
}


module.exports = {
    executeQuery
}

main.js

const pg = require('pg')
var Log = require('fancy-log');
var jsonPath = require('jsonpath');
var validator = require('validator');
var isEmpty = require('is-empty-array')
const argv = require('yargs').argv
require('custom-env').env(argv.env)

var db = require('./db');
var checker = require('./checklist')



async function foo(){
    await db.executeQuery("SELECT * from table_name",[])
}

foo()

Also same error here:

Database TypeError: Cannot read property 'txn_id' of undefined

You probably solved this already, but since there are no answers, in case someone needs help with this in the future.

TL;DR: You have to remove +1 from txn_id = await rows[Math.floor(Math.random() * rowCount + 1)].txn_id .

rows is an array of length N (N rows found in table_name ) with indices from 0 to N-1, and rowCount equals (in this case) rows.length ; and since:

1) 0 <= Math.random() < 1
2) 0 <= Math.random() * rowCount < N
3) 1 <= Math.random() * rowCount + 1 < N+1
4) 1 <= Math.floor(Math.random() * rowCount + 1) < N+1 (only natural numbers now)

then Math.floor(Math.random() * rowCount + 1) produces indeces from 1 to N, which is why sometimes (in case of N) rows[Math.floor(Math.random() * rowCount + 1)] equals undefined .

Also, await is not needed here: await rows[Math.floor(Math.random() * rowCount)] ; you already awaited for the query to finish here const { rows, rowCount } = await query(queryParam,conditions) .

Only place await in front of an expression which returns a Promise, otherwise it's doing nothing. ( suggested )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM