a
    dg3                     @  s   d Z ddlmZ ddlZddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZmZm Z  dZ!dZ"dZ#G dd de
Z$G dd de
Z%dS )z(Chain for interacting with SQL Database.    )annotationsN)AnyDictListOptional)Chain)LLMChain)DECIDER_PROMPTPROMPTSQL_PROMPTS)BasePromptTemplate)QUERY_CHECKER)SQLDatabase)CallbackManagerForChainRun)BaseLanguageModel)PromptTemplate)
ConfigDictFieldmodel_validatorintermediate_stepsz	SQLQuery:z
SQLResult:c                   @  s4  e Zd ZU dZded< dZded< eddZd	ed
< dZded< dZ	ded< dZ
ded< dZded< dZded< dZded< dZded< dZded< dZded< edddZedded d!d"d#d$Zed%d&d'd(Zed%d&d)d*Zd6d+d,d+d-d.d/Zedd&d0d1Zed7d2d	dd!d d3d4d5ZdS )8SQLDatabaseChaina  Chain for interacting with SQL Database.

    Example:
        .. code-block:: python

            from langchain_experimental.sql import SQLDatabaseChain
            from langchain_community.llms import OpenAI, SQLDatabase
            db = SQLDatabase(...)
            db_chain = SQLDatabaseChain.from_llm(OpenAI(), db)

    *Security note*: Make sure that the database connection uses credentials
        that are narrowly-scoped to only include the permissions this chain needs.
        Failure to do so may result in data corruption or loss, since this chain may
        attempt commands like `DROP TABLE` or `INSERT` if appropriately prompted.
        The best way to guard against such negative outcomes is to (as appropriate)
        limit the permissions granted to the credentials used with this chain.
        This issue shows an example negative outcome if these steps are not taken:
        https://github.com/langchain-ai/langchain/issues/5923
    r   	llm_chainNzOptional[BaseLanguageModel]llmT)excluder   databasezOptional[BasePromptTemplate]prompt   inttop_kquerystr	input_keyresult
output_keyFbool
return_sqlreturn_intermediate_stepsreturn_directuse_query_checkerquery_checker_promptZforbid)Zarbitrary_types_allowedextrabefore)moder   r   )valuesreturnc                 C  s^   d|v rZt d d|vrZ|d d urZ|d }|dpDt|jt}t|d |d|d< |S )Nr   zDirectly instantiating an SQLDatabaseChain with an llm is deprecated. Please instantiate with llm_chain argument or using the from_llm class method.r   r   r   r   r   )warningswarngetr   dialectr
   r   )clsr-   r   r    r5   m/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_experimental/sql/base.pyraise_deprecationI   s    z"SQLDatabaseChain.raise_deprecation	List[str]r.   c                 C  s   | j gS z?Return the singular input key.

        :meta private:
        r!   selfr5   r5   r6   
input_keysZ   s    zSQLDatabaseChain.input_keysc                 C  s   | j s| jgS | jtgS dS z@Return the singular output key.

        :meta private:
        Nr&   r#   INTERMEDIATE_STEPS_KEYr<   r5   r5   r6   output_keysb   s    zSQLDatabaseChain.output_keysDict[str, Any]$Optional[CallbackManagerForChainRun]inputsrun_managerr.   c              
   C  s  |p
t  }|| j  dt }|j|| jd |d}| jj|d}|t	| j
| jj|dgd}| jd ur| jjD ]}|| ||< qvg }	z&|	|  | jjf d| i| }
| jr| j|
iW S | jsT|j|
d| jd	 |	|
 |	d
|
i t|
v r|
td  }
t|
v r8|
td  }
| j|
}|	t	| n| jpjttddgd}t| jj|d}|
| jjd}|jf d| i| }|	| |j|d| jd	 |	d
|i | j|}|	t	| |}
|jd| jd |jt	|d| jd	 | jr"|}nt|jd| jd ||
 d| d7 }||d< |	|  | jjf d| i| }|	| |j|d| jd	 | j|i}| j r|	|t!< |W S  t"y } z|	|_#|W Y d }~n
d }~0 0 d S )N
)verbosetable_names_to_use)table_namesz
SQLResult:)inputr   r3   
table_infostop	callbacksgreencolorrI   sql_cmd   r   r   r3   )templateZinput_variablesr/   )r   r3   z
SQLResult: yellowz
Answer:rL   )$r   get_noop_managerr!   	SQL_QUERYon_textrI   r2   r   Zget_table_infor    r   r3   ZmemoryZmemory_variablesappendcopyr   Zpredict	get_childstripr%   r#   r(   split
SQL_RESULTrunr)   r   r   r   r   r'   r&   rA   	Exceptionr   )r=   rF   rG   _run_managerZ
input_textrJ   rM   
llm_inputskr   rS   r"   r)   Zquery_checker_chainZquery_checker_inputsZchecked_sql_commandZfinal_resultZchain_resultexcr5   r5   r6   _callm   s    











zSQLDatabaseChain._callc                 C  s   dS )NZsql_database_chainr5   r<   r5   r5   r6   _chain_type   s    zSQLDatabaseChain._chain_typer   )r   dbr   kwargsr.   c                 K  s2   |pt |jt}t||d}| f ||d|S )a  Create a SQLDatabaseChain from an LLM and a database connection.

        *Security note*: Make sure that the database connection uses credentials
            that are narrowly-scoped to only include the permissions this chain needs.
            Failure to do so may result in data corruption or loss, since this chain may
            attempt commands like `DROP TABLE` or `INSERT` if appropriately prompted.
            The best way to guard against such negative outcomes is to (as appropriate)
            limit the permissions granted to the credentials used with this chain.
            This issue shows an example negative outcome if these steps are not taken:
            https://github.com/langchain-ai/langchain/issues/5923
        r/   )r   r   )r   r2   r3   r
   r   )r4   r   rh   r   ri   r   r5   r5   r6   from_llm   s    zSQLDatabaseChain.from_llm)N)N)__name__
__module____qualname____doc____annotations__r   r   r   r   r   r!   r#   r%   r&   r'   r(   r)   r   Zmodel_configr   classmethodr7   propertyr>   rB   rf   rg   rj   r5   r5   r5   r6   r      s>   
 a r   c                	   @  s   e Zd ZU dZded< ded< dZded< d	Zded
< dZded< ee	e
fdddddd dddZeddddZeddddZd#dddddd Zeddd!d"ZdS )$SQLDatabaseSequentialChaina,  Chain for querying SQL database that is a sequential chain.

    The chain is as follows:
    1. Based on the query, determine which tables to use.
    2. Based on those tables, call the normal SQL database chain.

    This is useful in cases where the number of tables in the database is large.
    r   decider_chainr   	sql_chainr   r    r!   r"   r#   Fr$   r&   r   r   r   r   )r   rh   query_promptdecider_promptri   r.   c                 K  s:   t j||fd|i|}t||dd}| f ||d|S )zLoad the necessary chains.r   rK   )r   r   r#   )rt   rs   )r   rj   r   )r4   r   rh   ru   rv   ri   rt   rs   r5   r5   r6   rj      s
    
z#SQLDatabaseSequentialChain.from_llmr8   r9   c                 C  s   | j gS r:   r;   r<   r5   r5   r6   r>   
  s    z%SQLDatabaseSequentialChain.input_keysc                 C  s   | j s| jgS | jtgS dS r?   r@   r<   r5   r5   r6   rB     s    z&SQLDatabaseSequentialChain.output_keysNrC   rD   rE   c           
        s   |p
t  }| jj }d|}|| j |d}dd |D  | jjf i |} fdd|D }|j	dd| j
d |j	t|d	| j
d
 | jj|| j d|i}	| j|	| ddS )Nz, )r   rK   c                 S  s   g | ]}|  qS r5   lower.0namer5   r5   r6   
<listcomp>)      z4SQLDatabaseSequentialChain._call.<locals>.<listcomp>c                   s   g | ]}|   v r|qS r5   rw   ry   Z_lowercased_table_namesr5   r6   r|   +  s   zTable names to use:rH   )endrI   rV   rQ   rJ   T)rO   Zreturn_only_outputs)r   rW   rt   r   Zget_usable_table_namesjoinr!   rs   Zpredict_and_parserY   rI   r    r\   )
r=   rF   rG   rb   Z_table_namesrK   rc   Ztable_names_from_chainrJ   Z
new_inputsr5   r~   r6   rf     s*    


z SQLDatabaseSequentialChain._callc                 C  s   dS )NZsql_database_sequential_chainr5   r<   r5   r5   r6   rg   <  s    z&SQLDatabaseSequentialChain._chain_type)N)rk   rl   rm   rn   ro   r!   r#   r&   rp   r
   r	   rj   rq   r>   rB   rf   rg   r5   r5   r5   r6   rr      s$   
	 rr   )&rn   
__future__r   r0   typingr   r   r   r   Zlangchain.chains.baser   Zlangchain.chains.llmr   Z$langchain.chains.sql_database.promptr	   r
   r   Zlangchain.schemar   Z-langchain_community.tools.sql_database.promptr   Z*langchain_community.utilities.sql_databaser   Z langchain_core.callbacks.managerr   Zlangchain_core.language_modelsr   Zlangchain_core.prompts.promptr   Zpydanticr   r   r   rA   rX   r_   r   rr   r5   r5   r5   r6   <module>   s&    S