You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Azure OpenAI与Langchain生成SQL时Schema名称缺失的问题

问题:Text to SQL生成的SQL缺少Schema名

我正在使用Azure OpenAI和Langchain实现Text to SQL功能,目标是从自然文本提取SQL查询。该功能基于CSV文件中的表详情(包含表名、表描述、Schema名字段)生成SQL,要求生成的SQL必须同时包含Schema名和表名,但目前生成的SQL未包含Schema名,请求排查解决。

代码

from operator import itemgetter
from langchain.chains.openai_tools import create_extraction_chain_pydantic
from langchain_core.pydantic_v1 import BaseModel, Field
from typing import List
import pandas as pd

def get_table_details():
    # Read the CSV file into a DataFrame
    table_description = pd.read_csv("database_table_descriptions.csv")
    table_docs = []

    # Iterate over the DataFrame rows to create Document objects
    table_details = ""
    for index, row in table_description.iterrows():
        table_details = table_details + "Table Name:" + row['table'] + "\n" + "Table Description:" + row['description'] +  "\n" + "Schema Name:" + row['schema'] +"\n\n"

    return table_details


class Table(BaseModel):
    """Table in SQL database."""

    name: str = Field(description="Name of table in SQL database.")
    schema_name: str = Field(description="schema of table in SQL database.")

table_details = get_table_details()
print(table_details)

table_details_prompt = f"""Return the names of ALL the SQL tables and names of ALL the SQL schema that MIGHT be relevant to the user question. \
The tables are:

{table_details}

Remember to include ALL POTENTIALLY RELEVANT tables, even if you're not sure that they're needed."""

table_chain = create_extraction_chain_pydantic(Table, llm, system_message=table_details_prompt)
def get_tables(tables: List[Table]) -> List[str]:
    tables  = [f"{table.schema_name}.{table.name}" for table in tables]
    return tables

select_table = {"input": itemgetter("question")} | create_extraction_chain_pydantic(Table, llm, system_message=table_details_prompt) | get_tables
chain = (
RunnablePassthrough.assign(schema_and_table_names_to_use=select_table) |
RunnablePassthrough.assign(query=generate_query).assign(
    result=itemgetter("query") | execute_query
)
)
res = chain.invoke({"question": "what is the ftpjndi for tradingpartner Rockwood for table qtc_asn"})

当前输出

{'question': 'what is the ftpjndi for tradingpartner Rockwood for table qtc_asn',
 'schema_and_table_names_to_use': ['mule.qtc_asn'],
 'query': 'SELECT "ftpjndi" FROM qtc_asn WHERE tradingpartner = \'RockwoodSyspro\' LIMIT 1;',
 'result': ''}

期望输出

{'question': 'what is the ftpjndi for tradingpartner Rockwood for table qtc_asn',
 'schema_and_table_names_to_use': ['mule.qtc_asn'],
 'query': 'SELECT "ftpjndi" FROM mule.qtc_asn WHERE tradingpartner = \'RockwoodSyspro\' LIMIT 1;',
 'result': 'abc/xyz'}

解决方案

1. 强化generate_query的提示词约束

问题核心在于生成SQL的环节未强制使用带Schema的完整表名。修改generate_query的提示模板,明确要求必须使用schema_and_table_names_to_use中的完整表名格式(schema.table):

def generate_query(inputs):
    prompt = f"""根据用户问题生成符合要求的SQL查询:
    用户问题:{inputs['question']}
    必须使用以下指定的完整表名(包含Schema):{inputs['schema_and_table_names_to_use']}
    注意:SQL中的表名必须严格采用`schema_name.table_name`格式,禁止仅使用表名。"""
    return llm.invoke(prompt).content

2. 确保generate_query正确接收参数

确认链的构建中,generate_query能正确访问到schema_and_table_names_to_use变量。当前链的结构已经传递了该参数,但需确保generate_query函数内部确实使用了这个参数来约束表名。

3. 优化表提取提示词(可选)

虽然当前表提取环节已正确返回带Schema的表名,但可以进一步强化提示词,确保返回的表信息明确关联Schema:

table_details_prompt = f"""返回所有与用户问题相关的SQL表名和对应的Schema名,必须以`schema_name.table_name`的格式返回所有可能相关的表,即使不确定是否需要。
可用表信息:
{table_details}"""

4. 验证数据库执行环境

如果数据库连接默认Schema为mule,LLM可能会省略Schema名,但根据需求必须强制添加,因此仍需通过提示词严格约束,避免依赖数据库默认配置。


内容的提问来源于stack exchange,提问作者Ganesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:22:32