1. 概述

本指南旨在指导开发人员如何使用 Python 的 pyodbc 库连接瀚高数据库 (HighGo V9)。

  • 核心机制pyodbc 是 Python 的数据库接口层,它必须依赖底层的 ODBC 驱动程序才能与数据库通信。
  • 驱动来源:瀚高数据库安装包已内置了专用的 ODBC 驱动。
  • 关键路径:驱动文件位于数据库安装目录的 ${HGDBHOME}/drivers/odbc/lib 下,理论上严禁使用系统自带的通用 PostgreSQL 驱动,以确保版本兼容性和功能完整性。

2. 环境准备

2.1 确认安装路径

假设您的瀚高数据库安装在以下路径(请根据实际情况替换):

  • 安装根目录 ($HGDBHOME): 以/home/highgo/hgdb-v9.0.5/为例。
  • ODBC 驱动目录: /home/highgo/hgdb-v9.0.5/drivers/odbc/lib/

2.2 验证驱动文件

在执行配置前,请先确认驱动文件存在:

ls -l /home/highgo/hgdb-v9.0.5/drivers/odbc/lib/*.so

预期输出应包含类似 psqlodbcw.sopsqlodbca.so的文件。

2.3 环境准备

确保已安装 pyodbc 库和unixODBC-devel环境:

yum install unixODBC-devel python3-pyodbc
pip3 install pyodbc

3. 配置 ODBC 驱动 (系统级)

3.1编辑驱动注册表

vim /etc/odbcinst.ini

增加以下内容。注意:Driver 路径必须绝对指向安装包内的文件。

[HighGoV9Driver]
Description=HGDB V9 driver for Linux
Driver=/home/highgo/hgdb-v9.0.5/drivers/odbc/lib/psqlodbcw.so
Setup=/home/highgo/hgdb-v9.0.5/drivers/odbc/lib/psqlodbcw.so
UsageCount=1

💡 提示:

  • [HighGoV9Driver] 是驱动的逻辑名称,后续配置将引用此名称。

4. Python 连接示例

提供两种连接方式:DSN 模式(推荐)和 直连模式。

4.1 方式一:直连模式

import pyodbc

def connect_hgdb_v9():
conn_str = (
"DRIVER={HighGoV9Driver};"
"SERVER=192.168.33.25;"
"PORT=1521;"
"DATABASE=highgo;"
"UID=highgo;"
"PWD=Hello@1234;"
"SSLmode=disable;"
)

try:
print("正在连接 highgo db V9...")
conn = pyodbc.connect(conn_str, autocommit=False)
print("✅ 连接成功!")

cursor = conn.cursor()

# 1. 查询数据库版本
cursor.execute("SELECT highgo_version();")
version = cursor.fetchone()
print(f"数据库版本: {version[0]}")

# 2. 创建测试表
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
print("表结构检查/创建完成。")

# 3. 插入数据
sql_insert = "INSERT INTO users (name, email) VALUES (?, ?)"
data = ("Alice", "alice@example.com")
cursor.execute(sql_insert, data)
conn.commit()
print("✅ 数据插入成功。")

# 4. 查询数据
cursor.execute("SELECT id, name, email, created_at FROM users WHERE name = ?", ("Alice",))
rows = cursor.fetchall()

print("\n--- 查询结果 ---")
for row in rows:
# 【修正点】使用索引访问:row[0]是id, row[1]是name...
# 或者使用 row[列名] 如果驱动支持 (通常 pyodbc 默认只支持索引)
# 为了保险和速度,推荐使用索引,或者打印 row 看看结构
print(f"ID: {row[0]}, Name: {row[1]}, Email: {row[2]}, Time: {row[3]}")

# 5. 更新数据示例
cursor.execute("UPDATE users SET email = ? WHERE name = ?", ("new_email@example.com", "Alice"))
conn.commit()
print("✅ 数据更新成功。")

except pyodbc.Error as e:
print(f"❌ 数据库错误: {e}")
if "01000" in str(e):
print("提示: 找不到驱动。")
elif "28P01" in str(e):
print("提示: 认证失败。")
elif "08001" in str(e):
print("提示: 连接失败。")

finally:
if 'conn' in locals():
conn.close()
print("🔒 连接已关闭。")

if __name__ == "__main__":
connect_hgdb_v9()
[highgo@localhost ~]$ python3 python_test_v9.py 
正在连接 highgo db V9...
✅ 连接成功!
数据库版本: 瀚高数据库管理系统V9.0-enterprise-9.0.4.2
表结构检查/创建完成。
✅ 数据插入成功。

--- 查询结果 ---
ID: 1, Name: Alice, Email: new_email@example.com, Time: 2026-03-18 15:04:52.259775
ID: 2, Name: Alice, Email: new_email@example.com, Time: 2026-03-18 15:07:18.303929
ID: 3, Name: Alice, Email: alice@example.com, Time: 2026-03-18 15:11:52.462044
ID: 4, Name: Alice, Email: alice@example.com, Time: 2026-03-18 15:12:38.825466
ID: 5, Name: Alice, Email: alice@example.com, Time: 2026-03-18 15:13:31.923586
✅ 数据更新成功。
🔒 连接已关闭。

4.2 方式二:使用DSN连接

4.2.1 添加数据源定义

编辑 /etc/odbc.ini (如果文件不存在则创建):

vim /etc/odbc.ini
[HighGoV9_DSN]
Description = HighGo Database V9 Connection
Driver = HighGoV9Driver
Servername = 192.168.33.25
Port = 1521
Database = highgo
Username = highgo
Password = Hello@1234
SSLmode = disable

💡 提示:

  • Driver 字段的值必须与 /etc/odbcinst.ini 中方括号内的名称完全一致。
  • [HighGoV9_DSN]是DSN的逻辑名,后续配置将引用此名称。
  • 仅为示例,密码信息不建议名文存储到该文件中,建议代码中动态写入。

4.2.2 DSN模式测试代码

import pyodbc

def connect_hgdb_dsn():
# DSN 连接方式
# 格式: "DSN=你的数据源名称;"
# 用户名和密码如果在 odbc.ini 里配了,这里可以省略;也可以在这里覆盖。
conn_str = "DSN=HighGoV9_DSN;"

# 如果 odbc.ini 没配密码,可以在这里补充:
# conn_str = "DSN=HighGoV9_DSN;UID=highgo;PWD=Hello@1234;"
try:
print(f"正在通过 DSN 'HighGoV9_DSN' 连接 HighGo DB...")

# 建立连接
conn = pyodbc.connect(conn_str, autocommit=False)
print("✅ DSN 连接成功!")
cursor = conn.cursor()

# 1. 验证连接信息 (查看当前用户和数据库)
cursor.execute("SELECT current_user, current_database();")
info = cursor.fetchone()
print(f"当前用户: {info[0]}, 当前数据库: {info[1]}")

# 2. 执行一个简单的查询测试
print("\n--- 执行测试查询 (SELECT 1 + 1) ---")
cursor.execute("SELECT 1 + 1 AS result;")
row = cursor.fetchone()
print(f"计算结果: {row[0]}")

# 3. 业务逻辑测试 (复用之前的表)
print("\n--- 业务数据测试 ---")

# 插入一条新数据 (Bob)
sql_insert = "INSERT INTO users (name, email) VALUES (?, ?)"
data = ("Bob", "bob@highgo.com")

try:
cursor.execute(sql_insert, data)
conn.commit()
print("✅ 新用户 'Bob' 插入成功。")
except pyodbc.Error as insert_err:
# 忽略主键冲突等常见错误,仅做演示
if "23505" in str(insert_err): # 23505 是唯一约束冲突
print("⚠️ 用户 'Bob' 可能已存在,跳过插入。")
else:
raise insert_err

# 查询所有用户
cursor.execute("SELECT id, name, email FROM users ORDER BY id DESC LIMIT 5;")
rows = cursor.fetchall()

print(f"\n{'ID':<5} | {'Name':<10} | {'Email':<20}")
print("-" * 40)
for row in rows:
# 使用索引访问
print(f"{row[0]:<5} | {row[1]:<10} | {row[2]:<20}")

except pyodbc.Error as e:
print(f"\n❌ 连接或执行错误: {e}")
error_code = str(e).split('[')[0].strip() if '[' in str(e) else "Unknown"

if "IM002" in str(e) or "Data source name not found" in str(e):
print("💡 提示: 找不到 DSN 'HighGoV9_DSN'。")
print(" 1. 检查 /etc/odbc.ini 文件是否存在且格式正确。")
print(" 2. 确认 [HighGoV9_DSN] 段落名称拼写无误。")
print(" 3. 确认 Driver 指向的驱动名称在 /etc/odbcinst.ini 中存在。")
elif "01000" in str(e):
print("💡 提示: 驱动加载失败。检查 Driver 路径是否正确。")
elif "08001" in str(e):
print("💡 提示: 网络不通或被拒绝。检查 IP、端口及防火墙。")
elif "28P01" in str(e):
print("💡 提示: 密码错误或用户不存在。")

finally:
if 'conn' in locals():
conn.close()
print("\n🔒 连接已关闭。")

if __name__ == "__main__":
connect_hgdb_dsn()
[highgo@localhost ~]$ python3 python_highgo_dsn.py 
正在通过 DSN 'HighGoV9_DSN' 连接 HighGo DB...
✅ DSN 连接成功!
当前用户: highgo, 当前数据库: highgo

--- 执行测试查询 (SELECT 1 + 1) ---
计算结果: 2

--- 业务数据测试 ---
✅ 新用户 'Bob' 插入成功。

ID | Name | Email
----------------------------------------
6 | Bob | bob@highgo.com
5 | Alice | new_email@example.com
4 | Alice | new_email@example.com
3 | Alice | new_email@example.com
2 | Alice | new_email@example.com

🔒 连接已关闭。