(由于技术原因,联网搜索暂不可用)
以下是进一步改进的实现方案,将SQL语句独立存储在.sql文件中并通过Python调用:
import oracledb
import json
import csv
import os
from pathlib import Path
from typing import List, Dict, Any
# 禁用Thick模式
oracledb.init_oracle_client(lib_dir=None)
def load_db_config(json_file: str) -> List[Dict[str, Any]]:
"""从JSON文件加载数据库配置(同上,略)"""
# ...(保持原有实现不变)
def load_sql_from_file(sql_file: str) -> str:
"""从SQL文件加载查询语句"""
try:
with open(sql_file, 'r', encoding='utf-8') as f:
sql = f.read().strip()
if not sql:
raise ValueError("SQL文件内容为空")
return sql
except FileNotFoundError:
raise FileNotFoundError(f"SQL文件 {sql_file} 不存在")
except UnicodeDecodeError:
raise ValueError("SQL文件编码错误,请使用UTF-8格式")
def execute_sql_from_files(config_file: str, sql_file: str, bind_params: tuple = None):
"""
主执行函数(从文件读取SQL)
:param config_file: 数据库配置文件路径
:param sql_file: 要执行的SQL文件路径
:param bind_params: SQL绑定参数
"""
try:
# 加载配置和SQL
db_configs = load_db_config(config_file)
sql = load_sql_from_file(sql_file)
print(f"成功加载SQL:
{sql}")
except Exception as e:
print(f"初始化失败: {str(e)}")
return
# ...(后续执行逻辑与之前相同,略)
# 保持原有遍历数据库连接和执行逻辑
# 只需将参数中的sql替换为从文件读取的内容
# ...(保持save_to_csv等辅助函数不变)
if __name__ == "__main__":
# 配置文件路径
CONFIG_FILE = "databases.json"
SQL_FILE = "query.sql" # 新增加的SQL文件
execute_sql_from_files(
config_file=CONFIG_FILE,
sql_file=SQL_FILE,
bind_params=(60,) # 绑定参数用法不变
)
新增文件说明
- SQL文件示例(query.sql)
-- 员工信息查询(支持注释)
SELECT
e.employee_id AS "工号",
e.first_name || ' ' || e.last_name AS "姓名",
TO_CHAR(e.hire_date, 'YYYY-MM-DD') AS "入职日期",
d.department_name AS "部门"
FROM
employees e
JOIN departments d ON e.department_id = d.department_id
WHERE
e.department_id = :1 -- 使用绑定参数
ORDER BY
e.hire_date DESC
改进亮点
-
SQL与代码分离
- 专用
.sql文件存储查询语句 - 支持SQL格式高亮和IDE智能提示
- 方便版本控制(不同SQL单独管理)
- 专用
-
增强的SQL加载功能
- 自动检测文件编码(强制UTF-8)
- 空文件内容校验
- 支持SQL注释和多行编写
-
执行流程优化
-
参数传递灵活性
- 绑定参数仍通过Python代码控制
- SQL文件支持命名参数(如
:department_id)
使用步骤
-
创建SQL文件
# 示例:创建带参数的查询 echo "SELECT * FROM orders WHERE order_date > :start_date" > query.sql -
执行程序
python oracle_runner.py \ --config databases.json \ --sql query.sql \ --params 2023-01-01 -
查看输出
output/ ├── dbhost1_1521_hrpdba.csv └── dbhost2_1521_salesdb.csv
扩展建议
-
参数化SQL文件
# 支持jinja2模板(需安装jinja2) from jinja2 import Template sql_template = Template(load_sql_from_file("query.sql")) rendered_sql = sql_template.render(min_salary=5000) -
多SQL文件批处理
SQL_DIR = "queries/" for sql_file in Path(SQL_DIR).glob("*.sql"): execute_sql_from_files(config_file, sql_file) -
执行日志记录
import logging logging.basicConfig( filename='sql_runner.log', format='%(asctime)s - %(levelname)s - %(message)s' )
该方案实现了数据库操作逻辑与业务查询的完全解耦,适合需要频繁修改查询条件的分析场景。

3853

被折叠的 条评论
为什么被折叠?



