Skip to content

Commit 08faf7b

Browse files
jaguarliujaguarliu
authored andcommitted
feat: 支持oracle版本
1 parent 75d8d52 commit 08faf7b

File tree

5 files changed

+120
-7
lines changed

5 files changed

+120
-7
lines changed

database_schema/factory.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from database_schema.inspectors import (
33
MySQLInspector,
44
SQLServerInspector,
5-
PostgreSQLInspector
5+
PostgreSQLInspector,
6+
OracleInspector
67
)
78

89
class InspectorFactory:
@@ -13,7 +14,8 @@ def create_inspector(db_type: str, **kwargs) -> object:
1314
mapping = {
1415
'mysql': MySQLInspector,
1516
'sqlserver': SQLServerInspector,
16-
'postgresql': PostgreSQLInspector
17+
'postgresql': PostgreSQLInspector,
18+
'oracle': OracleInspector
1719
}
1820

1921
if db_type not in mapping:
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from sqlalchemy.sql import text
2+
from .base import BaseInspector
3+
from sqlalchemy.engine import reflection
4+
from urllib.parse import quote_plus
5+
6+
class OracleInspector(BaseInspector):
7+
"""Oracle元数据获取实现"""
8+
9+
def __init__(self, host: str, port: int, database: str,
10+
username: str, password: str, schema_name: str = None, **kwargs):
11+
super().__init__(host, port, database, username, password, schema_name)
12+
self.schema_name = username.upper() # Oracle模式名通常与用户名一致[3,8](@ref)
13+
14+
def build_conn_str(self, host: str, port: int, database: str,
15+
username: str, password: str) -> str:
16+
# 使用cx_Oracle驱动,支持SID或Service Name[6,8](@ref)
17+
return (
18+
f"oracle+cx_oracle://{quote_plus(username)}:{quote_plus(password)}"
19+
f"@{host}:{port}/?service_name={database}"
20+
)
21+
22+
def get_table_names(self, inspector: reflection.Inspector) -> list[str]:
23+
return inspector.get_table_names(schema=self.schema_name) # 需指定schema[3](@ref)
24+
25+
def get_table_comment(self, inspector: reflection.Inspector,
26+
table_name: str) -> str:
27+
# 查询ALL_TAB_COMMENTS视图[3,5](@ref)
28+
with self.engine.connect() as conn:
29+
sql = text("""
30+
SELECT COMMENTS
31+
FROM ALL_TAB_COMMENTS
32+
WHERE OWNER = :owner
33+
AND TABLE_NAME = :table_name
34+
""")
35+
return conn.execute(sql, {
36+
'owner': self.schema_name,
37+
'table_name': table_name
38+
}).scalar() or ""
39+
40+
def get_column_comment(self, inspector: reflection.Inspector,
41+
table_name: str, column_name: str) -> str:
42+
# 查询ALL_COL_COMMENTS视图[3](@ref)
43+
with self.engine.connect() as conn:
44+
sql = text("""
45+
SELECT COMMENTS
46+
FROM ALL_COL_COMMENTS
47+
WHERE OWNER = :owner
48+
AND TABLE_NAME = :table_name
49+
AND COLUMN_NAME = :column_name
50+
""")
51+
return conn.execute(sql, {
52+
'owner': self.schema_name,
53+
'table_name': table_name,
54+
'column_name': column_name
55+
}).scalar() or ""
56+
57+
def normalize_type(self, raw_type: str) -> str:
58+
# 标准化Oracle类型(如去除精度信息)[3,5](@ref)
59+
return raw_type.split('(')[0].split('%')[0].upper()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{# Oracle专用模板 #}
2+
{% extends "base_prompt.jinja" %}
3+
4+
{% block optimization_rules %}
5+
1. 索引优化策略:
6+
- 优先创建复合索引覆盖WHERE+SELECT字段
7+
- 对高频查询字段建立函数索引
8+
- 大数据量表使用位图索引
9+
2. 查询优化规范:
10+
- 使用绑定变量避免硬解析
11+
- 分区表查询必须指定分区键
12+
- 关联查询驱动表记录量需最小
13+
3. 执行计划控制:
14+
- 强制走索引使用/*+ INDEX(table_name index_name) */
15+
- 避免全表扫描的FILTER操作
16+
4. 特殊语法要求:
17+
- 时间范围使用TO_DATE()显式转换
18+
- 分页查询使用ROWNUM伪列
19+
{% endblock %}
20+
21+
{% block validation_rules %}
22+
1. 统计信息验证:
23+
- 自动检查LAST_ANALYZED时间,超过7天提示更新
24+
2. 执行计划验证:
25+
- 通过DBMS_XPLAN检查ACCESS_PREDICATES
26+
- 确保INDEX RANGE SCAN优于TABLE ACCESS FULL
27+
3. 性能基线检查:
28+
- WHERE条件字段必须有统计直方图
29+
- 多表关联必须存在连接条件索引
30+
{% endblock %}
31+
32+
{% block example_section %}
33+
## 输出示例:
34+
SELECT /*+ INDEX(emp emp_dept_idx) */
35+
e.employee_id AS "工号",
36+
(e.salary * 1.1) AS "调整薪资",
37+
TO_CHAR(e.hire_date, 'YYYY-MM-DD') AS "入职日期"
38+
FROM
39+
employees e
40+
INNER JOIN
41+
departments d ON e.department_id = d.department_id
42+
WHERE
43+
e.job_id = 'IT_PROG'
44+
AND d.location_id IN (1700, 1800)
45+
AND e.hire_date BETWEEN TO_DATE('2020-01-01', 'YYYY-MM-DD') AND SYSDATE
46+
ORDER BY
47+
e.hire_date DESC
48+
FETCH FIRST 100 ROWS ONLY;
49+
{% endblock %}

tools/rookie_text2data.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ parameters:
3535
- label:
3636
en_US: SQL Server
3737
value: sqlserver
38+
- label:
39+
en_US: Oracle
40+
value: oracle
3841
- name: limit
3942
type: number
4043
required: false
@@ -76,7 +79,7 @@ parameters:
7679
- name: host
7780
type: string
7881
required: true
79-
form: form
82+
form: llm
8083
label:
8184
en_US: Database ip/host
8285
zh_Hans: 数据库IP/域名
@@ -89,7 +92,7 @@ parameters:
8992
- name: port
9093
type: number
9194
required: true
92-
form: form
95+
form: llm
9396
min: 1
9497
max: 65535
9598
label:
@@ -104,7 +107,7 @@ parameters:
104107
- name: db_name
105108
type: string
106109
required: true
107-
form: form
110+
form: llm
108111
label:
109112
en_US: Database name
110113
zh_Hans: 数据库名称
@@ -143,7 +146,7 @@ parameters:
143146
- name: username
144147
type: string
145148
required: true
146-
form: form
149+
form: llm
147150
label:
148151
en_US: Username
149152
zh_Hans: 用户名
@@ -156,7 +159,7 @@ parameters:
156159
- name: password
157160
type: secret-input
158161
required: true
159-
form: form
162+
form: llm
160163
label:
161164
en_US: Password
162165
zh_Hans: 密码

workspace.difypkg

2.28 KB
Binary file not shown.

0 commit comments

Comments
 (0)