杰瑞科技汇

Python如何连接Oracle数据库?

安装 cx_Oracle

你需要安装 cx_Oracle 库,最简单的方式是使用 pip

Python如何连接Oracle数据库?-图1
(图片来源网络,侵删)
pip install cx_Oracle

重要提示:依赖 Oracle 客户库

cx_Oracle 是一个 Python 接口,它需要 Oracle 客户库(如 Instant Client)才能与 Oracle 数据库通信,你的环境中必须安装了相应的 Oracle 客户库。

  • Windows:Oracle Instant Client 下载页面 下载适合你系统的版本(如 "Windows 64-bit"),然后解压到一个目录(C:\oracle\instantclient_19_10)。
  • Linux (Debian/Ubuntu): 你可以使用 apt 安装。
    sudo apt-get update
    sudo apt-get install libaio1
    sudo apt-get install oracle-instantclient-basic
  • Linux (RHEL/CentOS/Fedora): 使用 yumdnf 安装。
    sudo yum install oracle-instantclient-release-el7
    sudo yum install oracle-instantclient-basic

配置环境变量(推荐)

为了让 cx_Oracle 能自动找到客户端库,你需要将客户端库的路径添加到系统的 PATH 环境变量中。

Python如何连接Oracle数据库?-图2
(图片来源网络,侵删)
  • Windows:

    1. 右键“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”。
    2. 在“系统变量”中找到 Path 变量,点击“编辑”。
    3. 点击“新建”,然后添加你解压 Instant Client 的路径(C:\oracle\instantclient_19_10)。
    4. 确认所有窗口。
  • Linux (以 bash 为例): 将以下行添加到你的 ~/.bashrc~/.profile 文件中,然后运行 source ~/.bashrc 使其生效。

    export LD_LIBRARY_PATH=/path/to/oracle/instantclient:$LD_LIBRARY_PATH

连接 Oracle 数据库

连接数据库需要以下信息:

  • 用户名: 你的数据库用户名。
  • 密码: 你的数据库密码。
  • 数据源标识: 这可以是多种形式,最常用的是 //主机名:端口号/服务名

基本连接示例

import cx_Oracle
# --- 1. 配置连接信息 ---
# 替换成你自己的数据库信息
username = "your_username"
password = "your_password"
dsn = "hostname:port/service_name" #  "mydb.example.com:1521/ORCLCDB"
# --- 2. 建立连接 ---
try:
    # 使用 with 语句可以确保连接在使用后被正确关闭
    with cx_Oracle.connect(username, password, dsn) as connection:
        print("成功连接到 Oracle 数据库!")
        # --- 3. 创建游标 ---
        # 游标用于执行 SQL 语句
        with connection.cursor() as cursor:
            # --- 4. 执行查询 ---
            sql_query = "SELECT * FROM your_table_name WHERE ROWNUM <= 5"
            cursor.execute(sql_query)
            # --- 5. 获取结果 ---
            # fetchone() 获取下一行
            # fetchmany(size) 获取指定数量的行
            # fetchall() 获取所有剩余的行
            print("\n查询结果:")
            for row in cursor:
                print(row)
except cx_Oracle.DatabaseError as e:
    # 获取错误信息
    error, = e.args
    print(f"数据库错误代码: {error.code}")
    print(f"数据库错误消息: {error.message}")

执行 DML 语句 (INSERT, UPDATE, DELETE)

执行修改数据的操作时,必须提交事务 (connection.commit()),否则更改不会永久保存到数据库。

Python如何连接Oracle数据库?-图3
(图片来源网络,侵删)
import cx_Oracle
username = "your_username"
password = "your_password"
dsn = "hostname:port/service_name"
try:
    with cx_Oracle.connect(username, password, dsn) as connection:
        with connection.cursor() as cursor:
            # --- 插入数据 ---
            insert_sql = "INSERT INTO employees (id, name, department) VALUES (employee_seq.NEXTVAL, :name, :dept)"
            employee_data = [("张三", "研发部"), ("李四", "市场部")]
            # executemany 用于批量插入,效率更高
            cursor.executemany(insert_sql, employee_data)
            # --- 提交事务 ---
            connection.commit()
            print(f"成功插入 {cursor.rowcount} 条新记录。")
            # --- 更新数据 ---
            update_sql = "UPDATE employees SET department = :new_dept WHERE name = :name"
            update_data = {"new_dept": "技术部", "name": "张三"}
            cursor.execute(update_sql, update_data)
            connection.commit()
            print(f"成功更新 {cursor.rowcount} 条记录。")
except cx_Oracle.DatabaseError as e:
    error, = e.args
    print(f"数据库错误代码: {error.code}")
    print(f"数据库错误消息: {error.message}")
    # 如果发生错误,回滚事务
    connection.rollback()
    print("已回滚所有更改。")

使用连接池

在高并发应用中,为每个请求创建和销毁连接是非常低效的,连接池可以重用数据库连接,显著提升性能。

import cx_Oracle
# --- 配置连接池 ---
pool = cx_Oracle.SessionPool(
    user="your_username",
    password="your_password",
    dsn="hostname:port/service_name",
    min=2,      # 连接池中最小连接数
    max=5,      # 连接池中最大连接数
    increment=1 # 当需要更多连接时,每次增加的数量
)
try:
    # 从连接池中获取一个连接
    with pool.acquire() as connection:
        with connection.cursor() as cursor:
            sql = "SELECT COUNT(*) FROM employees"
            cursor.execute(sql)
            count = cursor.fetchone()[0]
            print(f"员工总数: {count}")
finally:
    # 关闭连接池
    pool.close()
    print("连接池已关闭。")

最佳实践与注意事项

  1. 始终使用 with 语句: with 语句能确保游标和连接在代码块执行完毕后自动关闭,即使在发生异常时也是如此,是防止资源泄漏的最佳方式。

  2. 参数化查询: 永远不要使用字符串拼接来构建 SQL 查询,这会导致 SQL 注入漏洞,始终使用命名参数(如 name)或位置参数()来传递数据。

    ❌ 错误示例 (SQL 注入风险):

    user_input = "admin' -- "
    sql = "SELECT * FROM users WHERE username = '" + user_input + "'"
    cursor.execute(sql)

    ✅ 正确示例 (参数化查询):

    user_input = "admin' -- "
    sql = "SELECT * FROM users WHERE username = :username"
    cursor.execute(sql, {"username": user_input})
  3. 处理大结果集: 如果查询返回大量数据,使用 cursor.fetchall() 会将所有数据加载到内存中,可能导致内存溢出,对于大结果集,应该逐行处理。

    cursor.execute("SELECT * FROM very_large_table")
    for row in cursor:  # 逐行迭代,内存友好
        process(row) # 处理每一行
  4. 设置客户端字符集: 如果你的数据库使用非 ASCII 字符集(如 AL32UTF8),为了确保 Python 字符串正确处理,可以在连接池或连接中指定字符集。

    # 在连接池中设置
    pool = cx_Oracle.SessionPool(..., encoding="UTF-8")
    # 在连接中设置
    connection = cx_Oracle.connect(..., encoding="UTF-8")
  5. 错误处理: 总是使用 try...except cx_Oracle.DatabaseError 来捕获数据库操作中可能发生的错误,并进行适当的处理(如记录日志、回滚事务等)。


任务 代码示例
安装库 pip install cx_Oracle
基本连接 with cx_Oracle.connect(user, pwd, dsn) as conn:
创建游标 with conn.cursor() as cursor:
执行查询 cursor.execute("SELECT ...")
获取数据 for row in cursor:
执行DML cursor.execute("INSERT ...")
conn.commit()
参数化查询 cursor.execute("SELECT ... WHERE name = :n", {"n": "张三"})
使用连接池 pool = cx_Oracle.SessionPool(...)
with pool.acquire() as conn:

希望这份详细的指南能帮助你顺利地在 Python 中连接和使用 Oracle 数据库!

分享:
扫描分享到社交APP
上一篇
下一篇