DB2表创建与Python插入、查询实操解析

如何通过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连接已关闭。")
相关推荐
2301_7735536225 分钟前
如何优化深分页场景下的回表代价_延迟关联与主键游标分页
jvm·数据库·python
志栋智能29 分钟前
从“成本中心”到“效率引擎”:超自动化巡检的转型之路
运维·数据库·自动化
weixin_5689960635 分钟前
Golang怎么实现跳表数据结构_Golang如何用Skip List实现有序数据的快速查找【方法】
jvm·数据库·python
蜜獾云36 分钟前
交易系统之数据库弱依赖解决方案
数据库·oracle
卢傢蕊40 分钟前
NoSQL 之Redis 集群
数据库·redis·nosql
2401_8371638941 分钟前
CSS如何实现列表项序号自定义_利用--before与content实现
jvm·数据库·python
u01091476042 分钟前
Go语言怎么做WASM_Go语言WebAssembly教程【对比】
jvm·数据库·python
pele1 小时前
HTML5中WebSocket构造函数及其初始化连接规范
jvm·数据库·python
衫水1 小时前
企业级 Text-to-SQL 完整执行流程
大数据·数据库·sql
m0_515098421 小时前
如何创建哈希分区表_PARTITION BY HASH解决数据分布不均与热点块
jvm·数据库·python