无法从 nodejs 模块导出数据库属性

Posted

技术标签:

【中文标题】无法从 nodejs 模块导出数据库属性【英文标题】:Unable to export db properties from nodejs module 【发布时间】:2022-01-15 02:25:33 【问题描述】:

我正在尝试从 javascript 模块导出存储在属性文件中的数据库属性。当我读取数据库属性文件时,Javascript 文件已经导出,并且无论我在其他模块中使用什么地方,数据属性都显示为未定义。

const Pool = require('pg').Pool;
const fs = require('fs')
const path = require('path');

class DbConfig 
    constructor(dbData) 
        this.pool = new Pool(
            user: dbData['user'],
            host: dbData['host'],
            database: dbData['database'],
            password: dbData['password'],
            max: 20,
            port: 5432
        );
    


function getdbconf() 
    const dbData = ;
    fs.readFile("../../db_properties.txt"), 'utf8', (err, data) => 
        if (err) 
            console.error(err)
            return
        
        // dbData = "user":"postgres", "password": "1234"...;
        return dbData;
    );

    

let db = new DbConfig(getdbconf());
let dbPool = db.pool;
console.log("dbpool : -> : ",dbPool); // username and password appear undefined
module.exports =  dbPool ;

有没有办法在从 Javascript 模块导出数据之前读取数据?

【问题讨论】:

【参考方案1】:

请创建一个新文件 (connection-pool.js) 并粘贴此代码:

const  Pool  = require('pg');

const poolConnection = new Pool(
  user: 'postgresUserName',
  host: 'yourHost',
  database: 'someNameDataBase',
  password: 'postgresUserPassword',
  port: 5432,
);

console.log('connectionOptions', poolConnection.options);

module.exports = poolConnection;

要使用它,请创建一个新文件 (demo-connection.js) 并粘贴以下代码:

const pool = require('./connection-pool');

pool.query('SELECT NOW();', (err, res) => 

    if (err) 
        // throw err;
        console.log('connection error');
        return;
    

    if (res) 
        console.log(res.rows);
        pool.end();
    
);

这是另一种选择?

【讨论】:

【参考方案2】:

通常使用dotenv 从.env 文件中读取数据库配置或任何其他敏感信息。

或者

您也可以从命令行本身提供 env,例如

DB_HOST=127.0.0.1 node index.js

在你的 index.js 中

console.log(process.env.DB_HOST)

【讨论】:

很好地调用环境变量和 dotenv,这很棒。在我的答案中添加了对您的答案的引用。【参考方案3】:

导出异步调用的结果

要导出异步获取的值,请导出一个 Promise。

const fs = require('fs/promises'); // `/promise` means no callbacks, Promise returned

const dbDataPromise = fs.readFile('fileToRead')); //`readFile` returns Promise now

module.exports = dbDataPromise;

导入

当你需要使用该值时,

const dbDataPromise = require('./dbdata');


async init() 
  const dbData = await dbDataPromise;


//or without async, using Promise callbacks
init() 
  dbDataPromise
    .then(dbData => the rest of your code that depends on dbData here);

当前代码损坏

请注意,上面粘贴的当前代码已损坏:

function getdbconf() 
    const dbData = ;
    fs.readFile("../../db_properties.txt"), 'utf8', (err, data) => 
        //[...] snipped for brevity 
        return dbData;
    );

fs.readFile "returns" dbData,但是没有什么可以返回,因为你在一个不是你自己调用的回调中。函数getdbconf 不返回任何内容。

显示let db = new DbConfig(getdbconf()); 的行将不起作用。它需要在回调中。

避免将所有代码放入回调(并“展平”它)的唯一方法是使用await,或使用readFileSync

避免问题

使用环境变量

Suhas Nama's suggestion 是一个很好的方法,并且是常见的做法。尝试将您需要的值放入环境变量中。

使用同步读取文件

虽然使用同步调用确实会阻塞事件循环,但可以在初始化期间、在您的应用启动并运行之前执行此操作。

这避免了将所有内容都放在回调中或必须导出 Promises 的问题,并且通常是最好的解决方案。

【讨论】:

以上是关于无法从 nodejs 模块导出数据库属性的主要内容,如果未能解决你的问题,请参考以下文章

node.js 基础操作

无法将数据从数据库导出到 csv 文件

异步 nodejs 模块导出

NodeJS 模块导出

如何导出csv nodejs

处理用千牛导出淘宝数据,供Logstash到Elasticsearch使用。(NodeJS)