注册
dmPython 使用经验分享
培训园地/ 文章详情 /

dmPython 使用经验分享

DM_080736 2026/09/04 88 0 0

dmPython 使用手册

DM 数据库的 Python 接口 dmPython,包括了 dmPython 的安装、dmPython 接口与一些使用案例。


1. 概述

1.1 dmPython 简介

dmPython 是达梦数据库官方提供的 Python 编程接口,是 Python 应用访问 DM 数据库的推荐方式。使用 dmPython,开发人员可以在 Python 程序中完成连接数据库、执行 SQL 语句、处理结果集、调用存储过程、操作大对象等数据库开发工作。

dmPython 遵循 Python 数据库 API 规范 2.0(PEP 249),符合该规范的应用可以以极低的成本从其他数据库迁移到达梦数据库。

1.2 体系结构

dmPython 采用"Python 模块 + DPI 动态库"的两层结构:

┌─────────────────────┐
│   Python 应用程序    │
├─────────────────────┤
│   dmPython(模块)   │   ← Python 层,遵循 DB-API 2.0
├─────────────────────┤
│   DPI 动态库         │   ← libdmdpi.so(Linux)/ libdmdpi.dll(Windows)
├─────────────────────┤
│   DM 数据库服务器    │   ← 默认端口 5236
└─────────────────────┘

dmPython 模块本身不直接实现网络协议,而是调用达梦通用的 DPI(DM Programming Interface)动态库与数据库通信。因此:

  • dmPython 必须配合 DPI 动态库才能运行,DPI 随达梦数据库安装包或驱动包一起发布;
  • 安装 dmPython 之前,必须先正确配置 DPI 所需的环境变量(见 2.2 节);
  • dmPython 与 DM 服务器版本无需严格一一对应,但建议使用与数据库同版本或更高版本的驱动。

1.3 主要特性

  • 遵循 DB-API 2.0(PEP 249),apilevel = '2.0'
  • 采用 qmark(问号 ?)风格的参数占位符;
  • 支持常见数据类型:字符、数值、日期时间、大对象(BLOB/CLOB)等;
  • 支持参数绑定、批量执行(executemany)、存储过程调用;
  • 支持 Windows、Linux(含麒麟、统信 UOS 等国产操作系统)等平台;
  • 无需额外中间件,客户端仅依赖 DPI 动态库。

2. dmPython 安装

2.1 安装前准备

dmPython 可以运行在任何安装了 Python 的平台上。安装前请确认下表所述的环境要求:

项目 要求
操作系统 Windows / Linux(x86_64、ARM 等主流架构)
Python 2.7 或 3.x 均可,建议 3.6 及以上版本
setuptools Python 版本 ≥ 3.12 时,必须确保 Python 同时安装了 setuptools 库
DM 软件 已安装达梦数据库,或已获取达梦驱动压缩包(用于提供 DPI 动态库与 dmPython 源码)
编译环境 源码安装时需要:Linux 下 gcc 与 python3-devel(python3-dev);Windows 下 Visual Studio Build Tools

2.1.1 安装 Python

Python 软件请用户自行前往 Python 官网下载。安装任何一个版本 Python 均可。如果 Python 版本大于等于 3.12,请务必确保 Python 同时安装了 setuptools 库:

pip install setuptools

安装时注意事项:

  • Windows:安装向导中勾选 "Add Python to PATH",可免去手工配置环境变量;
  • Linux:多数发行版已自带 Python,可通过包管理器安装;若 Python ≥ 3.12 且采用源码方式安装 dmPython,需先确认 setuptools 已安装。

成功安装 Python 之后,可查看 Python 版本号:

# Windows python --version # Linux python3 --version

提示:一台机器上可能同时存在多个 Python 版本。后续安装 dmPython 时,请务必使用与运行应用相同的那个解释器(例如统一使用 python3 -m pip install .),否则会出现 "No module named dmPython" 的问题(见第 6 章 FAQ)。

2.1.2 获取 dmPython 与 DPI 驱动

第一步,安装达梦数据库或者下载达梦驱动压缩包。

  • 方式一:安装达梦数据库,具体的安装步骤可参考《DM8 安装手册》。安装完成后,dmPython 源码位于 DM 安装目录 dmdbms/drivers/python/dmPython 中(Windows 下形如 C:\dmdbms\drivers\python\dmPython,Linux 下形如 /dm/dmdbms/drivers/python/dmPython)。

  • 方式二:从达梦官方技术服务网站下载对应平台、对应数据库版本的驱动压缩包,解压后同样可得到 drivers/python/dmPython 源码目录及 DPI 动态库。

提示:部分版本的驱动包中,drivers/python 目录下按 Python 版本细分为多个子目录(并可能提供预编译的 whl 文件),请选择与当前 Python 版本匹配的目录。

2.2 配置环境变量

dmPython 的运行需要使用 DPI 动态库。因此用户需提前配置好环境变量,使用环境变量指定 DPI 的位置。

2.2.1 Linux 环境

Linux 环境下,用户须手动将 DPI 动态库所在目录(即 DM 安装目录中的 BIN 目录,或者 drivers 目录中的 dpi 目录)加入到 LD_LIBRARY_PATH 环境变量中,并设置环境变量 DM_HOME 等于 DM 安装目录或者 drivers 目录。

# 方式一:数据库安装目录的 bin 目录(推荐) export DM_HOME=/dm/dmdbms export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DM_HOME/bin # 方式二:仅使用驱动包时,指向 drivers 下的 dpi 目录 export DM_HOME=/dm8/drivers export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dm8/drivers/dpi

若希望重启后仍然生效,可将上述命令写入 /etc/profile(所有用户生效)或 ~/.bash_profile(当前用户生效),然后执行 source 使其立即生效:

echo 'export DM_HOME=/dm/dmdbms' >> ~/.bash_profile echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DM_HOME/bin' >> ~/.bash_profile source ~/.bash_profile

配置完成后可验证 DPI 动态库是否存在:

ls -l $DM_HOME/bin/libdmdpi.so

2.2.2 Windows 环境

Windows 环境下,将 DM 安装目录的 bin 目录(其中包含 DPI 动态库 libdmdpi.dll)加入系统 PATH 环境变量,并新建 DM_HOME 变量指向 DM 安装目录:

  1. 右键"此电脑"→"属性"→"高级系统设置"→"环境变量";
  2. 在"系统变量"中新建:变量名 DM_HOME,变量值 C:\dmdbms
  3. 在"系统变量" Path 中追加:%DM_HOME%\bin
  4. 确定保存后,重新打开命令行窗口使配置生效。

命令行临时生效的方式:

set DM_HOME=C:\dmdbms set PATH=%PATH%;%DM_HOME%\bin

2.3 安装 dmPython

dmPython 源码位于达梦安装目录 dmdbms\drivers\python\dmPython 中,安装程序为 setup.py

进入到 setup.py 所在的源码目录,执行命令:

cd /dm/dmdbms/drivers/python/dmPython # 方式一:传统安装(需要已配置好 DPI 环境变量) python3 setup.py install

也可以使用 pip 进行安装(便于后续统一卸载、管理依赖,推荐):

# 方式二:pip 源码安装 python3 -m pip install . # 方式三:若驱动包中提供了预编译 whl 文件,直接安装 python3 -m pip install dmPython-*.whl

卸载方式:

python3 -m pip uninstall dmPython

注意

  1. 安装前请先完成 2.2 节的环境变量配置,并重新打开终端,否则安装程序找不到 DPI 动态库会报错 cannot locate an Dameng software installation
  2. 源码安装需要编译环境(Linux 需要 gcc 与 python3-devel;Windows 需要 VS Build Tools),若缺少编译环境请优先使用 whl 方式安装;
  3. Linux 下普通用户对 site-packages 无写权限时会报权限错误,处理方式见第 6 章 FAQ。

2.4 验证安装

第一步,验证模块可正常导入:

python3 -c "import dmPython; print(dmPython.apilevel, dmPython.paramstyle)"

**第二步**,验证可正常连接数据库(数据库服务已启动,账号密码请按实际情况修改):

```bash
python3 -c "import dmPython; conn = dmPython.connect(user='SYSDBA', password='SYSDBA001', server='127.0.0.1', port=5236); print('连接成功'); conn.close()"

正常输出:

连接成功

两步均通过,说明 dmPython 安装成功。


3. 快速开始

3.1 编写测试 Python 文件

新建 test_dmpython.py
图片1.png

3.2 运行

python3 test_dmpython.py

3.3 运行结果

图片2.png

4. dmPython 接口说明

dmPython 遵循 DB-API 2.0 规范,接口分为三个层次:模块级接口(建立连接)、连接对象 Connection(管理连接与事务)、游标对象 Cursor(执行 SQL 与处理结果集)。

4.1 模块级接口

接口 / 属性 说明
dmPython.connect(...) 创建数据库连接,返回 Connection 对象
dmPython.apilevel 常量 '2.0',表示支持的 DB-API 版本
dmPython.threadsafety 模块线程安全级别
dmPython.paramstyle 常量 'qmark',参数占位符风格为 ?
dmPython.STRING / BINARY / NUMBER / DATETIME / ROWID 类型常量,用于与 description 中的列类型比较
dmPython.PG_UTF8 / dmPython.PG_GBK 客户端编码常量,供 local_code 参数使用

dmPython.connect 常用参数:

参数 说明 默认值
user 登录用户名 无,必填
password 登录密码 无,必填
server 数据库服务器 IP 或主机名 localhost
port 数据库监听端口 5236
local_code 客户端字符集编码,中文环境建议显式指定为 dmPython.PG_UTF8 与操作系统环境相关
login_timeout 登录超时时间(秒) 驱动默认值
dsn 以连接串方式传入连接信息(与服务名方式二选一)

其余连接属性(如通信加密、超时控制等)请以驱动源码目录中随附的官方文档为准。

示例:

conn = dmPython.connect(user='SYSDBA', password='SYSDBA001',                         server='192.168.10.101', port=5236,                         local_code=dmPython.PG_UTF8)

4.2 连接对象(Connection)

方法 说明
cursor() 创建并返回一个游标对象
commit() 提交当前事务
rollback() 回滚当前事务
close() 关闭连接,释放资源

事务说明:

  • dmPython 默认不自动提交,执行 INSERT / UPDATE / DELETE 后需要显式调用 commit(),否则连接关闭时未提交的修改将丢失;
  • 出现异常时调用 rollback() 回滚,可保证数据的原子性与一致性(用法见 5.4 节);
  • 连接使用完毕后应及时 close(),推荐使用 try...finally 保证资源释放。

4.3 游标对象(Cursor)

方法 / 属性 说明
execute(sql[, parameters]) 执行一条 SQL 语句,占位符使用 ?,返回受影响行数(可由 rowcount 获取)
executemany(sql, seq_of_parameters) 批量执行同一条 SQL,参数为"参数元组"的序列,常用于批量增删改
fetchone() 获取结果集下一行,无数据返回 None
fetchmany(size) 获取结果集下若干行
fetchall() 获取结果集剩余全部行
description 只读属性,结果集列描述信息(列名、类型等 7 元组组成的列表),仅 SELECT 后有效
rowcount 只读属性,上一次 execute 影响(或返回)的行数
callproc(procname[, parameters]) 调用存储过程
close() 关闭游标

重要:dmPython 的 paramstyleqmark,SQL 中使用 ? 作为参数占位符(而不是 %s):

cur.execute("select * from emp where dept_id = ? and salary > ?", (10, 5000))

4.4 数据类型支持

dmPython 与 Python 3 内置类型之间的常用映射如下(完整映射见附录 A):

DM 类型 Python 写入类型 Python 读取返回类型
CHAR / VARCHAR / TEXT str str
TINYINT / SMALLINT / INT / BIGINT int int
DEC / DECIMAL / NUMERIC decimal.Decimal decimal.Decimal
FLOAT / DOUBLE / REAL float float
BIT bool bool
DATE datetime.date datetime.date
TIME datetime.time datetime.time
TIMESTAMP datetime.datetime datetime.datetime
BINARY / VARBINARY bytes bytes
BLOB bytes bytes
CLOB str str

4.5 异常处理

dmPython 遵循 DB-API 2.0 的异常层次结构,可通过捕获相应异常进行错误处理:

Error
 ├── InterfaceError          # 接口本身错误(如连接已关闭)
 └── DatabaseError           # 数据库相关错误
      ├── DataError          # 数据处理错误(如数值溢出、除零)
      ├── OperationalError   # 操作错误(如连接断开、网络异常)
      ├── IntegrityError     # 完整性约束错误(如违反主键/唯一约束)
      ├── InternalError      # 数据库内部错误
      ├── ProgrammingError   # SQL 错误(如语法错误、表不存在)
      └── NotSupportedError  # 不支持的接口或操作

5. 使用案例

以下案例均假设已通过 4.1 节的方式建立连接 conn,并已创建游标 cur = conn.cursor()

5.1 参数化查询(防 SQL 注入)

始终使用 ? 占位符绑定参数,不要用字符串拼接 SQL,既安全又能提升执行效率:

# 反例:存在 SQL 注入风险 # sql = "select * from emp where name = '" + name + "'" # 正例:参数化查询 name = '张三' cur.execute("select id, name, salary from emp where name = ?", (name,)) print(cur.fetchall()) # LIKE 模糊查询 cur.execute("select id, name from emp where name like ?", ('张%',)) print(cur.fetchall())

5.2 批量插入(executemany)

批量写入时应使用 executemany 代替循环 execute,可显著减少交互次数、提升性能:

data = [(i, '员工%03d' % i, 5000 + i) for i in range(1, 10001)] cur.executemany("insert into emp(id, name, salary) values(?, ?, ?)", data) conn.commit() print('插入行数:', cur.rowcount)

性能建议:

  1. 使用 executemany 而非逐条 execute
  2. 大批量数据分批提交(例如每 5000~10000 行提交一次),避免大事务;
  3. 插入前可以先删除或禁用表上的索引、约束,插入完成后重建。

5.3 查询结果处理

cur.execute("select id, name, salary from emp where dept_id = ? order by id", (10,)) # 逐行处理(推荐,内存占用小) row = cur.fetchone() while row:     emp_id, emp_name, salary = row     print(emp_id, emp_name, salary)     row = cur.fetchone() # 一次性取回全部(结果集较大时慎用) cur.execute("select count(*) from emp") (total,) = cur.fetchone() print('总行数:', total)

5.4 事务管理

利用 commit / rollback 保证一组操作的原子性:

try:     cur.execute("update account set balance = balance - 100 where id = ?", (1,))     cur.execute("update account set balance = balance + 100 where id = ?", (2,))     conn.commit()          # 两条同时成功,提交     print('转账成功') except dmPython.DatabaseError as e:     conn.rollback()        # 任一条失败,全部回滚     print('转账失败,已回滚:', e)

5.5 大对象(BLOB / CLOB)操作

# 写入 BLOB:以二进制方式读取文件 with open('photo.jpg', 'rb') as f:     blob_data = f.read() cur.execute("insert into t_file(id, content) values(?, ?)", (1, blob_data)) # 写入 CLOB:以文本方式读取文件 with open('readme.txt', 'r', encoding='utf-8') as f:     clob_data = f.read() cur.execute("insert into t_doc(id, content) values(?, ?)", (1, clob_data)) conn.commit() # 读取 BLOB cur.execute("select content from t_file where id = ?", (1,)) (data,) = cur.fetchone() with open('photo_copy.jpg', 'wb') as f:     f.write(data)

5.6 调用存储过程

准备数据:

create table emp(id int primary key, salary numeric(10, 2)); insert into emp values(1, 5000); commit; create or replace procedure raise_salary(p_id int, p_raise numeric) as begin   update emp set salary = salary + p_raise where id = p_id;   commit; end; /

Python 中调用:

cur.callproc('RAISE_SALARY', (1, 1000)) # 验证结果 cur.execute("select salary from emp where id = ?", (1,)) print(cur.fetchone())      # 输出: (Decimal('6000'),)

说明:对于含 OUT 参数的存储过程,callproc 按照 DB-API 2.0 约定返回参数新值序列,不同驱动版本的实现细节略有差异,建议以随驱动文档为准;也可以改用"存储过程写入结果表 + SELECT 查询"的方式获取输出。

函数可以直接在 SELECT 语句中调用:

cur.execute("select my_func(?)", (1,))

5.7 与 pandas 配合使用

dmPython 遵循 DB-API 2.0 规范,可作为 pandas 的数据源直接使用:

import pandas as pd import dmPython conn = dmPython.connect(user='SYSDBA', password='SYSDBA001',                         server='127.0.0.1', port=5236) df = pd.read_sql('select id, name, salary from emp', conn) print(df.head()) conn.close()

5.8 简单封装示例

将常用操作封装成工具类,便于工程化使用:

# -*- coding: utf-8 -*- import dmPython class DmDb:     """dmPython 数据库操作简单封装"""     def __init__(self, host, port, user, password):         self.conn = dmPython.connect(server=host, port=port,                                      user=user, password=password,                                      local_code=dmPython.PG_UTF8)     def query(self, sql, params=None):         """查询,返回全部结果行"""         cur = self.conn.cursor()         try:             cur.execute(sql, params or ())             return cur.fetchall()         finally:             cur.close()     def execute(self, sql, params=None):         """执行增删改,返回受影响行数;失败自动回滚"""         cur = self.conn.cursor()         try:             cur.execute(sql, params or ())             self.conn.commit()             return cur.rowcount         except Exception:             self.conn.rollback()             raise         finally:             cur.close()     def close(self):         self.conn.close() if __name__ == '__main__':     db = DmDb('127.0.0.1', 5236, 'SYSDBA', 'SYSDBA001')     try:         print(db.query('select id, name from test_dmpython'))     finally:         db.close()

6. 常见问题(FAQ)

6.1 安装类问题

(1)dmPython 安装报错:error: can't create or remove files in install directory

错误原因:操作系统目录权限问题,dmdba 用户对 Python 的 site-packages 目录没有写权限。

解决方案:使用 root 用户修改该目录权限,使 dmdba 用户对该目录有写权限:

[root@localhost ~]# mkdir -p /usr/local/lib64/python3.7/site-packages/ [root@localhost ~]# chmod 777 /usr/local/lib64/python3.7/site-packages/

更推荐的做法(避免放宽系统目录权限):

# 使用 pip 的用户级安装 python3 -m pip install . --user # 或使用虚拟环境 python3 -m venv venv source venv/bin/activate python3 -m pip install .

(2)dmPython 安装报错:cannot locate an Dameng software installation

错误原因:这是 DPI 环境问题,因为 dmPython 的运行需要使用 DPI 动态库,需要将 DPI 所在目录(通常是数据库安装目录的 bin 目录)加入系统的环境变量。

解决方法:设置 PATH 包含 DPI 驱动,如下:

[root@localhost ~]# export PATH=$PATH:/dm/dmdbms/bin

同时按 2.2.1 节配置 DM_HOMELD_LIBRARY_PATH,并重新执行安装命令。

(3)Python ≥ 3.12 安装时报错:No module named 'setuptools'(或 pkg_resources 相关错误)

错误原因:Python 3.12 起不再默认捆绑 setuptools。

解决方法

pip install setuptools

然后重新执行安装。

(4)源码安装编译报错:Python.h: No such file or directory

错误原因:缺少 Python 头文件开发包。

解决方法

# CentOS / RHEL / 麒麟 yum install -y python3-devel gcc # Ubuntu / Debian apt-get install -y python3-dev build-essential

(5)安装时报错找不到编译器(Windows:Unable to find vcvarsall.bat;Linux:gcc: command not found

错误原因:源码安装 dmPython 需要本机编译环境。

解决方法:Windows 安装 Visual Studio Build Tools;Linux 安装 gcc;或直接使用驱动包中提供的预编译 whl 文件安装(见 2.3 节方式三)。

6.2 导入与加载类问题

(6)import dmPython 报错:No module named dmPython

错误原因:没有成功安装 dmPython,或安装到的 Python 环境与运行程序的环境不一致。

解决方法

① 如果没有成功安装 dmPython,请按第 2 章步骤安装 dmPython;

② 机器上存在多个 Python 版本时,请确认安装与运行使用的是同一个解释器。统一使用以下方式安装可避免该问题:

python3 -m pip install .

(7)import dmPython 报错:ImportError: libdmdpi.so: cannot open shared object file(Linux)或 DLL load failed(Windows)

错误原因:dmPython 的运行需要使用 DPI 动态库,应该将 DPI 所在目录(通常是 $DM_HOME/bin 目录)加入系统的环境变量。

解决方法

[root@localhost ~]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dm/dmdbms/bin

Windows 下将 C:\dmdbms\bin 加入 PATH。配置后需重新打开终端窗口再运行程序(见 2.2 节)。

6.3 连接类问题

(8)连接报错:网络通信异常 / 登录超时

错误原因:数据库服务未启动、IP 或端口不正确、网络不通或被防火墙拦截。

解决方法

① 确认数据库实例已启动:

# Linux 下查看服务状态 systemctl status DmServiceDMSERVER.service

② 确认 serverport 参数正确(DM 默认端口 5236);

③ 测试网络连通性:ping 主机、telnet 127.0.0.1 5236

④ 检查防火墙是否放通了数据库端口。

(9)连接报错:用户名或密码错误(登录失败)

错误原因:账号密码不正确,或安装数据库后已修改过 SYSDBA 默认密码。

解决方法:确认使用正确的用户名与密码。达梦初始默认口令为 SYSDBA/SYSDBA(实际以安装时的设置为准)。若密码中含有特殊字符,注意代码中的转义。

(10)查询结果中文乱码

错误原因:客户端编码与数据库字符集不一致。

解决方法:连接时显式指定 local_code 参数,使其与数据库字符集匹配(UTF-8 字符集的库指定为 PG_UTF8):

conn = dmPython.connect(user='SYSDBA', password='SYSDBA001',                         server='127.0.0.1', port=5236,                         local_code=dmPython.PG_UTF8)

6.4 附:ODBC 相关问题

以下两个问题属于 ODBC 环境配置问题,与 dmPython 无直接关系,但经常在搭建达梦开发环境时一并遇到,故一并收录。

(11)配置 ODBC 环境后执行 isql 报错:Can't open lib '/dm8/drivers/odbc/libdodbc.so': file not found

错误原因:没有配置 LD_LIBRARY_PATH 环境变量。

解决方案:配置 LD_LIBRARY_PATH 环境变量:

[root@localhost ~]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dm8/drivers/odbc/

(12)配置 ODBC 环境执行后 isql 报错:Data source name not found

[dmdba@localhost ~]$ isql dm -v

错误原因:数据源名称 DSN 不正确。

解决方法:检查 odbc.ini 中配置的数据源名称,输入正确的数据源名称。


附录 A:数据类型映射表

DM 类型 Python 写入类型 Python 读取返回类型
CHAR / CHARACTER str str
VARCHAR / VARCHAR2 str str
TEXT / LONGVARCHAR str str
TINYINT / SMALLINT / INT / INTEGER / BIGINT int int
DEC / DECIMAL / NUMBER / NUMERIC decimal.Decimal decimal.Decimal
FLOAT / DOUBLE / REAL / DOUBLE PRECISION float float
BIT bool bool
DATE datetime.date datetime.date
TIME / TIME(p) datetime.time datetime.time
TIMESTAMP / TIMESTAMP(p) datetime.datetime datetime.datetime
BINARY / VARBINARY bytes bytes
BLOB / IMAGE bytes bytes
CLOB / TEXT(大对象) str str

附录 B:dmPython.connect 常用参数速查

参数 类型 说明 默认值
user str 登录用户名 必填
password str 登录密码 必填
server str 服务器地址(IP 或主机名) localhost
port int 服务器端口 5236
local_code int 客户端编码(dmPython.PG_UTF8 / dmPython.PG_GBK 与系统环境相关
login_timeout int 登录超时时间(秒) 驱动默认
dsn str 连接串形式的连接描述
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服