如何通过Python实现DB2数据库的连接、数据插入与查询操作。
数据库编码是GBK,所以配置是GBK
一、前置准备:环境搭建与依赖安装
在开始操作前,需完成环境配置和依赖安装,确保Python与DB2能够正常通信。
1.1 环境要求
-
数据库:DB2数据库(本地或远程部署,本文以远程DB2为例,数据库名称casb,地址10.1.1.38,端口25010);
-
Python环境:Python 3.7及以上版本;
-
依赖库:需要安装用于DB2连接的ibm_db、ibm_db_dbi库,以及用于数据处理的pandas库。
1.2 依赖安装命令
打开命令行,执行以下命令安装所需依赖(建议使用虚拟环境,避免依赖冲突):
pip install ibm-db ibm-db-dbi pandas
说明:ibm_db是IBM官方提供的DB2数据库Python驱动,用于建立数据库连接;ibm_db_dbi提供了符合Python DB API 2.0标准的接口,适配pandas等库;pandas用于便捷地处理查询结果,以表格形式展示数据。
二、DB2表创建:基础语法与实操案例
创建DB2表是数据存储的基础,需根据业务需求设计字段类型、主键、约束等。本文以"员工信息表emp_info"为例,讲解表创建的完整流程,字段设计贴合实际业务,同时适配后续Python插入、查询操作。
2.1 表结构设计
结合员工信息管理场景,设计emp_info表,字段如下(与后续Python代码完全匹配,避免字段不兼容):
| 字段名 | 字段类型 | 约束 |
|---|---|---|
| id | INT | 自增主键 |
| name | VARCHAR(50) | 非空 |
| address | VARCHAR(500) | 无 |
| salary | DECIMAL(12,2) | 无 |
2.2 DB2建表语句(两种执行方式)
DB2建表语句支持直接通过数据库客户端执行。
方式1:通过DB2客户端执行(推荐,适用于一次性建表)
打开DB2客户端(如DBeaver、DataGrip、DB2 Control Center),连接目标数据库后,执行以下SQL语句:
bash
-- 创建员工信息表emp_info
CREATE TABLE emp_info (
id INT GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
address VARCHAR(500),
salary DECIMAL(12, 2)
);
-- 可选:给表和字段添加注释,提升可读性
COMMENT ON TABLE emp_info IS '员工信息表,用于存储员工基本信息';
COMMENT ON COLUMN emp_info.id IS '自增主键,员工唯一标识';
COMMENT ON COLUMN emp_info.name IS '员工姓名,非空约束';
COMMENT ON COLUMN emp_info.address IS '员工联系地址';
COMMENT ON COLUMN emp_info.salary IS '员工月薪,精确到分';
说明:IDENTITY关键字用于设置自增主键,START WITH 1表示自增起始值为1,INCREMENT BY 1表示每次递增1;VARCHAR类型用于存储字符串,DECIMAL(12,2)表示总长度12位,其中小数位2位,适合存储金额类数据。
Python操作DB2:连接、插入与查询
完成DB2表创建后,通过Python实现数据库连接、数据插入和查询,全程实操可复制,重点解决中文乱码、数据类型适配、事务提交等常见问题。
3.1 Python连接DB2(关键步骤)
连接DB2时,需注意编码设置(避免中文乱码)、连接参数配置(数据库地址、端口、账号密码等),具体代码如下:
python
# 导入所需库
import pandas as pd
import ibm_db
import ibm_db_dbi
from decimal import Decimal # 用于处理小数金额,避免精度丢失
import os
# 关键:设置DB2编码(适配中文,对应GBK代码页1386)
os.environ['DB2CODEPAGE'] = '1386'
# 建立DB2连接
ibm_db_conn = ibm_db.connect(
"DATABASE=casb;HOSTNAME=10.1.1.38;PORT=25010;PROTOCOL=TCPIP;UID=db2inst1;PWD=xxxx;",
"", "",
charset='gbk',
encoding='gbk'
)
# 转换为DB API 2.0兼容连接,适配pandas
conn = ibm_db_dbi.Connection(ibm_db_conn)
关键说明:
-
DB2CODEPAGE环境变量设置为1386,对应GBK编码,解决中文插入、查询时的乱码问题;
-
连接参数中,DATABASE为数据库名称,HOSTNAME为数据库地址,PORT为端口,UID和PWD为数据库账号密码,需根据实际情况修改;
-
Decimal类用于处理小数,避免Python浮点数精度丢失,适配DB2的DECIMAL类型字段。
3.2 Python向DB2插入数据(参数化插入,安全高效)
插入数据时,推荐使用参数化插入(避免SQL注入风险),同时需注意事务提交(DB2默认不自动提交,需手动执行commit),具体代码如下:
预编译插入代码
python
#_*_coding:utf-8_*_
import pandas as pd
import ibm_db
import ibm_db_dbi
from decimal import Decimal # 1. 加上这个导入
import os
# 正确设置GBK(代码页1386)对应的环境变量
os.environ['DB2CODEPAGE'] = '1386'
# 连接时charset/encoding仍用'gbk'(驱动会对应到1386代码页)
ibm_db_conn = ibm_db.connect(
"DATABASE=casb;HOSTNAME=10.1.1.38;PORT=25010;PROTOCOL=TCPIP;UID=db2inst1;PWD=xxx;",
"", "",
charset='gbk',
encoding='gbk'
)
conn = ibm_db_dbi.Connection(ibm_db_conn)
# ---------------------------------------------------------------------------
# 1. 新增一条记录(参数化)
# ---------------------------------------------------------------------------
# 2. 把 ? 改成 %s
insert_sql = "INSERT INTO emp_info (name, address, salary) VALUES (?,?,?)"
name, address, salary = '张三', '北京市海淀区中关村大街1号', Decimal("15000.50")
stmt = ibm_db.prepare(ibm_db_conn, insert_sql)
if stmt:
ibm_db.execute(stmt, (name, address, salary))
ibm_db.commit(ibm_db_conn) # 3. 加上提交
print("新增记录数: 1")
else:
print("INSERT prepare 失败")
# ---------------------------------------------------------------------------
# 2. 查询记录并打印到前台
# ---------------------------------------------------------------------------
select_sql = "SELECT id, name, address, salary FROM emp_info ORDER BY id"
print("\n--- 查询结果 ---")
print(select_sql)
pd.set_option('display.width', 1000, 'display.max_rows', 1000000, 'display.max_columns', None)
df = pd.read_sql(select_sql, conn)
print(df)
ibm_db.close(ibm_db_conn)
print("\n连接已关闭。")
查询结果展示(示例):
--- 员工信息查询结果 ---
id name address salary
1 张三 北京市海淀区中关村大街1号 15000.50
2 李四 上海市浦东新区张江高科技园区 18000.00
3 王五 广州市天河区天河路385号 16500.75
4 赵六 深圳市南山区科技园 17200.20
五、常见问题与解决方案
数据库编码是GBK,所以这里配置GBK
5.1 中文乱码问题
现象:插入中文数据后,查询显示乱码;
解决方案:确保两个关键设置:① 环境变量DB2CODEPAGE=1386;② 连接数据库时,charset和encoding均设为gbk(如代码中所示)。
以上DB2是GBK编码
如果是UTF-8编码需要改配置:
os.environ['DB2CODEPAGE'] = '1208'
charset='utf-8',
encoding='utf-8'
查询编码参考:https://blog.csdn.net/fen_fen/article/details/155495438
5.2 数据插入失败,提示"数据类型不匹配"
现象:插入salary字段时报错,提示与DECIMAL类型不匹配;
解决方案:使用Decimal类处理小数,避免直接使用Python浮点数(如Decimal("15000.50")),确保数据类型与DB2表字段一致。
5.3 插入数据后,查询不到数据
现象:执行插入操作后,无报错,但查询结果为空;
解决方案:DB2默认不自动提交事务,需在执行insert后,手动调用ibm_db.commit(ibm_db_conn),确保数据写入数据库。
六、非预编译插入代码
#_*_coding:utf-8_*_
import pandas as pd
import ibm_db
import ibm_db_dbi
from decimal import Decimal
import os
# 正确设置GBK(代码页1386)对应的环境变量
os.environ['DB2CODEPAGE'] = '1386'
# 连接时charset/encoding仍用'gbk'(驱动会对应到1386代码页)
ibm_db_conn = ibm_db.connect(
"DATABASE=casb;HOSTNAME=10.1.1.38;PORT=25010;PROTOCOL=TCPIP;UID=db2inst1;PWD=xxx;",
"", "",
charset='gbk',
encoding='gbk'
)
conn = ibm_db_dbi.Connection(ibm_db_conn)
# ---------------------------------------------------------------------------
# 直接插入(无预编译,无 f-string,老Python也能用)
# ---------------------------------------------------------------------------
name = '张三'
address = '北京市海淀区中关村大街1号'
salary = Decimal("15000.50")
# 用最传统的 %s 格式化,绝对兼容
insert_sql = "INSERT INTO emp_info (name, address, salary) VALUES ('%s', '%s', %s)" % (name, address, salary)
# 直接执行
ibm_db.exec_immediate(ibm_db_conn, insert_sql)
ibm_db.commit(ibm_db_conn)
print("直接插入成功!")
# ---------------------------------------------------------------------------
# 查询
# ---------------------------------------------------------------------------
select_sql = "SELECT id, name, address, salary FROM emp_info ORDER BY id"
print("\n--- 查询结果 ---")
pd.set_option('display.width', 1000, 'display.max_rows', 1000000, 'display.max_columns', None)
df = pd.read_sql(select_sql, conn)
print(df)
ibm_db.close(ibm_db_conn)
print("\n连接已关闭。")