Oracle Database 连接器¶
Oracle Database 经 ODPI-C 走 OCI 接入。
Dosi 编译原生 Oracle SQL,包括用 FETCH FIRST 做限制、用
TRUNC(x, 'FMT') 做时间粒度截断、INTERVAL '1' MONTH 这样的带引号
interval 字面量,以及不带 AS 的表别名。
ODPI-C 会编进 Dosi 的 Oracle executor,但 Oracle 原生客户端库不会随 Dosi 一起打包。免费的 Oracle Instant Client 只在 Dosi 第一次打开 Oracle 连接时加载。因此,SQL 编译或 dry run 成功, 并不能证明当前运行环境可以真正执行这条 SQL。
使用前准备¶
执行 Oracle 查询前,运行 Dosi 的机器需要:
- Oracle Instant Client Basic Package(如果精简字符集已够用,也可以用 Basic Light);
- 一个能连接目标服务、并可读取语义模型所引用对象的 Oracle 账号。
Dosi 不需要 Instant Client SDK、SQL*Plus、Tools、JDBC 或 ODBC 包。
安装包必须匹配 Dosi 二进制所在的操作系统和 CPU 架构;从 Python 使用
dosi-engine 时,还必须匹配 Python 解释器的架构。
| 运行平台 | Instant Client 安装包 | 部署说明 |
|---|---|---|
| Ubuntu 20.04 或 22.04;Debian 10、11 或 12 | linux.x64 或 linux.arm64 的 Linux ZIP |
安装 libaio1;当前 23ai 包要求 glibc 2.28 或更高版本。 |
| Ubuntu 24.04;Debian 13 | linux.x64 或 linux.arm64 的 Linux ZIP |
安装 libaio1t64;可能还需要排错里的兼容库名。 |
| RHEL 8 或 9 | 匹配的 EL8/EL9 RPM,或 Linux ZIP | RPM 最适合系统级安装;ZIP 方式还要安装 libaio。 |
| 使用 ARM64 运行时的 macOS | macos.arm64 Basic DMG |
原生 Apple Silicon Dosi 或 Python。 |
| 使用 x86-64 运行时的 macOS | macos.x64 Basic DMG |
Intel 或 Rosetta Dosi/Python。Oracle 最新的 Intel 包是 19.16,列出的系统支持只到 macOS Monterey,应视为遗留平台。 |
这张表说明的是 Dosi 的实际部署路径,不等同于 Oracle 对操作系统的认证声明。 不支持跨架构组合、32 位 Client,以及 Alpine Linux 等基于 musl 的发行版。 某个平台有 Instant Client,也不代表 Dosi 一定为它发布了预编译产物。
Oracle Client 23ai 可以连接 Oracle Database 19c 及以上版本,但这只是 Client 与 Server 的互操作结论,并不代表在 23ai 上生成和测试的 SQL 会自动兼容 所有旧数据库版本。具体边界见版本兼容性与限制。
安装 Oracle Instant Client¶
安装脚本会识别 Linux 或 macOS,检查 dosi 的架构(找不到 Dosi 时检查
Python),选择固定版本的 Basic 包,校验 SHA-256,安装原生依赖并配置加载器。
把下面代码块整段复制到实际运行 Dosi 的 shell 中:
# 可选:检查指定运行时,或选择 universal binary 的实际 slice。
# export DOSI_RUNTIME=/path/to/python3
# export DOSI_ARCH=x86_64
oracle_installer="$(mktemp)"
curl -fsSL https://dosi.datus.ai/assets/install-oracle-instant-client.sh \
-o "$oracle_installer" &&
bash "$oracle_installer" &&
eval "$(bash "$oracle_installer" --print-env)"
rm -f "$oracle_installer"
unset oracle_installer
--print-env 在 Linux 上没有输出;在 macOS 上,最后一条 eval 会在当前 shell
中通过 DYLD_LIBRARY_PATH 导出匹配的目录。如果要检查指定的 Dosi 或 Python
可执行文件,请在运行安装代码块之前设置并导出 DOSI_RUNTIME。对于无法确定实际
运行 slice 的 universal 非 Python 可执行文件,脚本不会猜测;请用
DOSI_ARCH=x86_64 或 DOSI_ARCH=arm64 显式选择。
脚本源码见
install-oracle-instant-client.sh。
它固定使用 Oracle 的 Linux x86-64、
Linux ARM64、
macOS ARM64
和 macOS Intel
下载页中的安装包。使用 --print-package 可以只查看选中的版本、URL、checksum
和目标目录,不执行安装。
连接配置¶
可以使用分开的连接字段:
datasources:
oracle:
type: oracle
host: db.internal
port: 1521
username: main
password: ${ORACLE_PASSWORD}
database: ORCLPDB1 # 服务名
也可以使用 EZConnect URL:
参数¶
| 键 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
type |
string | 是 | — | oracle |
host |
string | 是* | — | *除非给了 uri:。 |
port |
int | 否 | 监听器默认 | 可选:EZConnect 也接受 //host/service。 |
username |
string | 是* | — | 分开写各字段时必填。 |
password |
string | 是* | — | 分开写各字段时必填。尽量用 ${VAR}。 |
database |
string | 是* | — | 这里填的是服务名,不是 schema。分开写各字段时必填。 |
uri |
string | 否 | — | oracle://user:pass@host:port/service。口令里带 @ 也没问题:主机从最后一个 @ 切分。 |
default |
bool | 否 | false |
见连接配置。 |
共享的 profile 格式还接受 schema、sslmode、sslrootcert、
arrow_flight_port、catalog、account、role、warehouse 和
compat_mode,但 Oracle 连接器不使用这些字段。特别是,schema: 不会执行
ALTER SESSION SET CURRENT_SCHEMA;见 schema 解析。
验证连接¶
最终验证必须执行真实查询。替换下面的模型、指标、维度和连接名,并在实际运行 Dosi 的同一个环境中执行:
$ dosi query --model model.yaml \
--metrics revenue --group-by orders.status --execute --connection oracle
查询返回数据,才说明 Instant Client、网络、凭据、服务名、对象权限和 SQL 都已
生效。出现 DPI-1047 表示运行进程仍然加载不到 Instant Client;出现网络错误或
ORA-... 则说明 Client 已经加载,剩余问题在连接或数据库侧。只编译 SQL 或
dry run 不能作为连接验证。
运行时行为¶
会话初始化¶
连接使用自动提交,并执行四条 ALTER SESSION。Dosi 把
TIME_ZONE = 'UTC' 固定为无时区取值约定,同时为 NLS_DATE_FORMAT、
NLS_TIMESTAMP_FORMAT 和 NLS_TIMESTAMP_TZ_FORMAT 使用 ISO 格式。
如果不设置这些 NLS 值,Oracle 常见的 DD-MON-RR 默认格式可能会拒绝
生成的 CAST('2024-01-01' AS DATE) 字面量。
schema 解析¶
在 Oracle 里,schema 就是用户。编译出的 SQL 会保留模型中的
<schema>.<table> 引用,因此登录账号必须拥有这些对象或具备访问权限。
如果要使用其他登录账号,应为它授权,并通过同义词暴露模型所需的名字;profile
里的 schema: 不会重定向对象解析。
有一处语义差异不会被归一:Oracle 把 '' 当成 NULL。
版本兼容性与限制¶
当前 Oracle 连接器及其可执行 SQL 用例集是在 Oracle Database 23ai Free 上 验证的。这不等于“完整支持所有 Oracle 版本”:
- Client 连通性: Instant Client 23ai 可以连接 Oracle Database 19c 及以上版本,前提是 Server 和网络接受该连接。
- 指标 SQL: Oracle 19c 和 21c 没有 23ai 的原生三参数
DATEDIFF。 生成的指标查询如果使用它,就不能在没有方言降级或模型修改的情况下移植到这些 版本。 - 测试数据灌入: Dosi 的 Oracle fixture 灌数会使用多行
INSERT、DROP TABLE IF EXISTS和原生BOOLEAN,这些是 23ai 特性。因此这套测试 初始化不能原样运行在 19c 或 21c 上,但这件事本身并不妨碍这些数据库执行普通的 只读指标查询。
在对 19c 或 21c 跑过专门的 SQL 用例集之前,应把它们视为“按查询判断是否兼容”, 而不是已正式验证的版本。Instant Client 则是另一条独立的运行时前提:原生库缺失 或无法加载时,任何 Oracle 查询都不能执行。
排错¶
| 报错或现象 | 原因与处理 |
|---|---|
提到 DPI-1047 的配置错误 |
ODPI-C 没有加载到兼容的 Instant Client。按安装 Oracle Instant Client处理,确认 Client 与 Dosi 架构一致,并检查所有原生依赖。 |
Ubuntu 24.04 或 Debian 13 上出现 libaio.so.1 => not found |
libaio1t64 可能只提供 libaio.so.1t64;按下方命令补兼容链接,再执行 ldconfig。 |
connection "x": oracle needs database: (the service name) |
database: 填服务名,例如 FREEPDB1,不是 schema。 |
connection "x": oracle needs username: / … needs password: |
分开写连接字段时,两者都必填。 |
connection "x": expected an oracle:// url |
uri: 必须使用 oracle:// scheme。 |
connection "x": oracle url needs user:pass@host/service |
URL 缺少凭据或服务名。 |
server rejected SQL (ORA-NNNNN): <message> |
Oracle 拒绝了编译出的语句。ORA-00942 通常是对象不可见或 schema 名不匹配;语法或函数错误也可能说明当前数据库版本没有对应特性。 |
安装脚本处理 libaio1t64 兼容问题时不需要 dpkg-dev。如果要手动恢复,先用
dpkg-query 找到已安装的库,再创建 Instant Client 需要的库名:
$ library="$(dpkg-query -L libaio1t64 | awk '/\/libaio\.so\.1t64$/ {print; exit}')"
$ sudo ln -sfn "$(basename "$library")" "$(dirname "$library")/libaio.so.1"
$ sudo ldconfig
排查 DPI-1047 时,如果要查看 ODPI-C 尝试过的全部位置,请在启动 Dosi 前
设置 DPI_DEBUG_LEVEL=64:
$ DPI_DEBUG_LEVEL=64 dosi query --model model.yaml \
--metrics revenue --execute --connection oracle
Instant Client 安装不需要设置 ORACLE_HOME;只有把可选的
tnsnames.ora、sqlnet.ora 等文件放在独立目录时,才需要设置
TNS_ADMIN。
参考链接¶
- 官网:https://www.oracle.com/database/
- 运行时客户端:Oracle Instant Client
- 安装说明:使用 ZIP 安装 Instant Client
- 兼容性:Oracle Database Client 软件要求
- URL 写法:Easy Connect 命名
- Dosi 配置:连接配置 · CLI