You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1 Mac下node-oracledb连接Oracle数据库失败求助

问题

基于node-oracledb的后端在Windows机器可正常连接学校Oracle数据库,但M1 Mac无法运行。已通过Rosetta切换至x64版本Node.js,执行oracledb.createPool()时出现异常:

  1. 移除try/catch后触发DPI-1047错误(无法找到64位Oracle客户端库)
  2. 按指引处理客户端库后,又出现ORA-24415错误(用户名缺失或为空)

相关代码:

const express = require('express');
const oracledb = require('oracledb');
if (process.platform === 'darwin') {
    try {
      console.log("Success");
      oracledb.initOracleClient({libDir: process.env.HOME + '/Downloads/instantclient_19_8'});
    } catch (err) {
      console.log("Failure");
      console.error('Whoops!');
      console.error(err);
      process.exit(1);
    }
}
const dotenv = require('dotenv');
const app = express();
const PORT = 5000;
dotenv.config();
var cors = require('cors');
app.use(cors());
app.use(express.json());

app.listen(PORT, ()=>{console.log(`listen to port ${PORT}`);})

database_initialized = false

async function init_database() {
    // The following should be wrapped in a try/catch
    await oracledb.createPool({
        user: process.env.USER_NAME,
        password: process.env.DB_PASSWORD,
        connectionString: process.env.CONNECTION_STRING
    });
    console.log("Successfully created connection pool");
    database_initialized = true
}

app.get('/', (req,res) => {
    res.send('Hello world!');
});

app.get('/get-customers', (req,res) => {
    async function fetchDataCustomers(){
        try {
            const connection = await oracledb.getConnection();

            oracledb.outFormat = oracledb.OUT_FORMAT_ARRAY;

            const query = process.env.QUERY_STR;;

            const result = await connection.execute(query);
            console.log("Completed request");
            
            try {
                await connection.close();
            }
            catch (err) {
                console.log("Encountered an error closing a connection in the connection pool.");
            }
            
            return result;
        } catch (error) {
            return error;
        }
    }

    fetchDataCustomers().then(dbRes => {
        res.send(dbRes);
    })
    .catch(err => {
        res.send(err);
    })
})

init_database();

可行解决方法

一、解决DPI-1047客户端库问题

  • 确认Instant Client版本兼容性:使用x64架构的Instant Client 19.8或21.x版本(通过Rosetta运行),不要用ARM原生版本
  • 修正客户端库路径:
    替换process.env.HOME + '/Downloads/instantclient_19_8'为绝对路径,比如'/Users/你的用户名/Downloads/instantclient_19_8',避免环境变量解析异常
    检查目录下是否存在libclntsh.dylib等核心库文件
  • 配置终端环境变量:启动Node前执行以下命令(或写入~/.zshrc持久生效):
    export DYLD_LIBRARY_PATH=/Users/你的用户名/Downloads/instantclient_19_8:$DYLD_LIBRARY_PATH
    export OCI_LIB_DIR=/Users/你的用户名/Downloads/instantclient_19_8
    export OCI_INC_DIR=/Users/你的用户名/Downloads/instantclient_19_8/sdk/include
    

二、修复ORA-24415用户名缺失问题

  • 调整dotenv加载时机:将dotenv.config()移到代码最顶部,确保环境变量在加载oracledb前就被读取:
    const dotenv = require('dotenv');
    dotenv.config(); // 提前加载环境变量
    const express = require('express');
    const oracledb = require('oracledb');
    // ... 后续代码
    
  • 验证环境变量有效性:在init_database函数开头添加日志,确认变量值是否正确:
    async function init_database() {
        console.log('USER_NAME:', process.env.USER_NAME);
        console.log('DB_PASSWORD:', process.env.DB_PASSWORD);
        console.log('CONNECTION_STRING:', process.env.CONNECTION_STRING);
        // ... 创建连接池代码
    }
    
  • 检查变量名拼写:确认.env文件中的变量名和代码中完全一致(比如是否是USER_NAME而非DB_USER)

三、其他必要检查

  • 确认Rosetta启用:打开终端的“显示简介”,勾选“使用Rosetta打开”,重启终端后再运行Node
  • 重装node-oracledb:删除node_modules和package-lock.json,在x64 Node环境下重新执行npm install,避免编译时架构不匹配
  • 验证连接字符串:确认学校Oracle的连接字符串格式正确,比如使用//主机名:端口/服务名格式,而非旧版SID格式

内容的提问来源于stack exchange,提问作者Brian.H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:55:17