安装 cx_Oracle 驱动
你需要安装 cx_Oracle 库,推荐使用 pip 进行安装。

pip install cx_Oracle
注意:
- Oracle 客户端:
cx_Oracle需要 Oracle 客户端库(如 Instant Client)才能与数据库通信,你需要根据你的操作系统和 Oracle 数据库版本下载并配置好 Instant Client。- Windows: 下载 Instant Client ZIP 包,然后将其解压到一个固定目录(
C:\oracle\instantclient_19_10),并将该目录添加到系统的PATH环境变量中。 - macOS (使用 Homebrew):
brew install instantclient-basic - Linux (Debian/Ubuntu): 可以使用
apt-get install oracle-instantclient19.10-full等命令安装。
- Windows: 下载 Instant Client ZIP 包,然后将其解压到一个固定目录(
配置好 Instant Client 后,你可以通过以下命令验证 Python 是否能找到它:
import cx_Oracle print(cx_Oracle.clientversion())
如果成功输出版本号,说明环境配置正确。
建立数据库连接
连接数据库需要提供用户名、密码、网络地址和数据库名(或服务名/SID)。

连接信息格式
cx_Oracle 使用一种特殊的连接字符串格式:username/password@host:port/service_name
username: 数据库用户名password: 密码host: 数据库服务器的 IP 地址或主机名port: 监听端口,通常是1521service_name: 数据库的服务名(推荐使用)SID: 数据库的标识符(旧版本常用,如果服务名不行可以尝试这个)
连接代码示例
import cx_Oracle
# --- 1. 定义连接信息 ---
# 请替换成你自己的数据库信息
username = "your_username"
password = "your_password"
dsn = "your_host:your_port/your_service_name" # "localhost:1521/XE"
# --- 2. 建立连接 ---
try:
# 创建连接对象
connection = cx_Oracle.connect(user=username, password=password, dsn=dsn)
print("数据库连接成功!")
# --- 3. 在这里执行你的数据库操作 ---
# ... (见下一节)
except cx_Oracle.DatabaseError as e:
# 捕获数据库连接错误
error, = e.args
print(f"数据库连接错误: {error.code} - {error.message}")
finally:
# --- 4. 关闭连接 ---
if 'connection' in locals() and connection:
connection.close()
print("数据库连接已关闭。")
执行 SQL 查询
连接成功后,你可以创建一个游标来执行 SQL 语句。
基本查询步骤:
- 从连接对象获取一个游标。
- 使用
cursor.execute()执行 SQL 查询。 - 使用
cursor.fetchall()获取所有结果行(返回一个列表),或cursor.fetchone()获取单行结果。 - 处理结果数据。
- 关闭游标。
示例代码 (接上面的连接代码):
# ... (连接代码部分不变)
try:
connection = cx_Oracle.connect(user=username, password=password, dsn=dsn)
print("数据库连接成功!")
# --- 获取游标 ---
cursor = connection.cursor()
# --- 执行查询 ---
# 使用占位符 %s 来防止 SQL 注入,即使参数是数字也建议这样做
sql_query = "SELECT employee_id, first_name, last_name, salary FROM employees WHERE department_id = :dept_id"
department_id = 50 # 示例部门ID
# 执行 SQL,参数以字典形式传递
cursor.execute(sql_query, {'dept_id': department_id})
# --- 获取结果 ---
# fetchall() 获取所有行
rows = cursor.fetchall()
print(f"\n部门 {department_id} 的员工信息:")
print("-" * 40)
# 遍历结果
for row in rows:
# row 是一个元组,(101, 'John', 'Doe', 9000)
emp_id, first_name, last_name, salary = row
print(f"ID: {emp_id:<5} 姓名: {first_name} {last_name:<10} 薪资: {salary:>10}")
# --- 获取列名 (非常有用) ---
column_names = [desc[0] for desc in cursor.description]
print("\n查询结果的列名:", column_names)
except cx_Oracle.DatabaseError as e:
error, = e.args
print(f"数据库操作错误: {error.code} - {error.message}")
finally:
# --- 关闭游标和连接 ---
if 'cursor' in locals() and cursor:
cursor.close()
if 'connection' in locals() and connection:
connection.close()
print("\n数据库连接已关闭。")
执行 DML 语句 (INSERT, UPDATE, DELETE)
对于修改数据的操作,执行后必须调用 connection.commit() 来提交事务,否则更改不会永久保存到数据库中。
示例:插入数据
import cx_Oracle
# ... (连接信息)
try:
connection = cx_Oracle.connect(user=username, password=password, dsn=dsn)
cursor = connection.cursor()
# 准备 SQL 和参数
sql_insert = "INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id) VALUES (:id, :fn, :ln, :email, SYSDATE, 'IT_PROG')"
new_employee_data = {
'id': 9999,
'fn': 'Python',
'ln': 'Test',
'email': 'python.test@example.com'
}
# 执行
cursor.execute(sql_insert, new_employee_data)
# 提交事务
connection.commit()
print(f"成功插入 {cursor.rowcount} 行数据。")
except cx_Oracle.DatabaseError as e:
# 发生错误时回滚
if 'connection' in locals() and connection:
connection.rollback()
error, = e.args
print(f"数据库操作错误: {error.code} - {error.message}")
finally:
if 'cursor' in locals() and cursor:
cursor.close()
if 'connection' in locals() and connection:
connection.close()
使用 with 语句(推荐的最佳实践)
为了确保游标和连接在任何情况下都能被正确关闭(即使发生错误),强烈建议使用 with 语句,它会自动处理资源的清理。

示例:使用 with 语句
import cx_Oracle
# ... (连接信息)
try:
# with 语句会自动处理 connection.close()
with cx_Oracle.connect(user=username, password=password, dsn=dsn) as connection:
print("数据库连接成功!")
# with 语句会自动处理 cursor.close()
with connection.cursor() as cursor:
sql = "SELECT first_name, salary FROM employees WHERE rownum <= 5"
cursor.execute(sql)
print("\n前5名员工信息:")
for row in cursor:
# row 是一个可以解包的序列
name, salary = row
print(f"姓名: {name:<15} 薪资: {salary:>10}")
except cx_Oracle.DatabaseError as e:
error, = e.args
print(f"数据库操作错误: {error.code} - {error.message}")
这个版本更简洁、更安全,是现代 Python 编程的推荐方式。
处理大数据集(使用 cursor.fetchmany())
当查询结果非常大时,使用 fetchall() 会一次性将所有数据加载到内存中,可能导致内存溢出,这时,应该使用 fetchmany(size) 分批获取数据。
# ... (连接代码)
try:
with cx_Oracle.connect(user=username, password=password, dsn=dsn) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM very_large_table")
# 每次获取 1000 行
while True:
rows = cursor.fetchmany(1000)
if not rows:
break # 没有更多数据了
# 处理这 1000 行数据
for row in rows:
process_row(row) # 假设有一个处理函数
except cx_Oracle.DatabaseError as e:
# ... (错误处理)
| 任务 | 关键代码/方法 | 说明 |
|---|---|---|
| 安装驱动 | pip install cx_Oracle |
需要 Oracle Instant Client 支持。 |
| 建立连接 | cx_Oracle.connect(user=..., dsn=...) |
dsn 格式为 host:port/service_name。 |
| 获取游标 | connection.cursor() |
游标是执行 SQL 的对象。 |
| 执行 SQL | cursor.execute(sql, params) |
使用 name 占位符防止 SQL 注入。 |
| 查询数据 | cursor.fetchall() / cursor.fetchone() |
获取所有或单行结果。 |
| 修改数据 | connection.commit() |
必须调用,否则事务不会提交。 |
| 回滚事务 | connection.rollback() |
发生错误时撤销未提交的更改。 |
| 关闭资源 | cursor.close() / connection.close() |
或使用 with 语句自动管理。 |
| 处理大数据 | cursor.fetchmany(size) |
分批获取,避免内存问题。 |
希望这份详细的指南能帮助你顺利地在 Python 中连接和操作 Oracle 数据库!
