Langchain SQLDatabaseChain无法访问Oracle同义词与视图表名求助
Oracle同义词/视图无法被Langchain SQLDatabaseChain识别的解决方案
问题描述
刚接触Langchain,构建text-to-sql应用时,使用SQLDatabaseChain无法访问Oracle数据库中的同义词与视图对应的表名,代码如下:
import os import sys import cx_Oracle from langchain.utilities import SQLDatabase from langchain.llms import OpenAI from langchain_experimental.sql import SQLDatabaseChain from sqlalchemy import create_engine import constants #Importing OpenAPIKey from constants file os.environ["OPENAI_API_KEY"] = constants.APIKEY # Declaring Database Details IP="IP Address" PORT="PORT" # 修正原拼写错误POSRT servicename="ORACLE_SERVICENAME" username="USERNAME" password="PASSWORD" # Developing the oracle Connection oracle_connection_string = f'oracle+cx_oracle://{username}:{password}@{cx_Oracle.makedsn(IP, PORT, service_name=servicename)}' engine=create_engine(oracle_connection_string, echo=True) db = SQLDatabase(engine) llm = OpenAI(temperature=0.01, verbose=True) db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True) while True: query = input("Query Please: ") # query = "Is employee code 7365 exist or not?" if query in ('q', 'quit', 'exit'): break sys.exit() value = db_chain.run(query) print(value)
排查与解决步骤
1. 开启视图支持并加载同义词
Langchain的SQLDatabase默认仅加载普通表,且不支持视图。需手动开启视图支持,并主动获取同义词列表加入加载范围:
from sqlalchemy import inspect # 初始化引擎后,先获取所有需要的对象 inspector = inspect(engine) # 获取普通表 tables = inspector.get_table_names() # 获取当前用户的视图和同义词 with engine.connect() as conn: # 获取视图列表 view_result = conn.execute("SELECT view_name FROM all_views WHERE owner = :owner", {"owner": username.upper()}) views = [row[0] for row in view_result] # 获取当前用户的同义词 synonym_result = conn.execute("SELECT synonym_name FROM all_synonyms WHERE owner = :owner", {"owner": username.upper()}) synonyms = [row[0] for row in synonym_result] # 合并表、视图、同义词 all_target_objects = tables + views + synonyms # 初始化SQLDatabase,开启视图支持并指定加载对象 db = SQLDatabase(engine, view_support=True, include_tables=all_target_objects)
2. 验证数据库用户权限
确保连接Oracle的用户具备以下权限:
- 对目标同义词、视图的
SELECT权限 - 访问
all_synonyms、all_views系统视图的权限(用于获取对象列表)
可通过执行以下SQL验证:
-- 检查视图权限 SELECT privilege FROM user_tab_privs WHERE table_name = 'TARGET_VIEW'; -- 检查同义词权限 SELECT privilege FROM user_tab_privs WHERE table_name = 'TARGET_SYNONYM';
3. 检查LLM生成的SQL逻辑
开启SQLDatabaseChain的中间步骤输出,查看LLM是否生成了包含同义词/视图的SQL:
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True, return_intermediate_steps=True) # 运行查询后打印中间步骤 value = db_chain(query) print(value['intermediate_steps'])
如果LLM未引用目标同义词/视图,可通过在提问中明确指定对象名称,或自定义table_info参数补充对象描述,引导LLM生成正确SQL。
4. 修正连接字符串问题
原代码中存在两处连接字符串错误:
PORT变量拼写为POSRT,需修正为PORT- 连接字符串重复使用
format方法,实际cx_Oracle.makedsn已生成完整地址,无需二次格式化,简化后的连接字符串更可靠
内容的提问来源于stack exchange,提问作者VijayaDurgaPrasad
相关产品推荐
相关产品推荐

