o
    ZhF                     @  s4  d dl mZ d dlZd dlZd dlmZmZmZmZm	Z	m
Z
mZ d dlZd dlmZ d dlmZmZ d dlmZmZ zd dlmZ W n eyQ   d dlmZ Y nw d dlmZ d d	lmZ d d
lmZ d dlmZ e ZdZ dZ!G dd deZ"G dd de"Z#G dd de"Z$G dd dZ%G dd deZ&dS )    )annotationsN)AnyDictIterableListOptionalTupleType)func)JSONUUID)Sessionrelationship)declarative_base)Document)
Embeddings)get_from_dict_or_env)VectorStorei   Z	langchainc                   @  s,   e Zd ZdZdZejedddej	dZdS )	BaseModelzBase model for all SQL stores.TZas_uuid)Zprimary_keydefaultN)
__name__
__module____qualname____doc__Z__abstract__
sqlalchemyColumnr   uuiduuid4 r   r   c/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/vectorstores/pgembedding.pyr      s    r   c                   @  sX   e Zd ZdZdZeejZee	Z
eddddZedddZe	ddddZdS )CollectionStorezCollection store.Zlangchain_pg_collectionEmbeddingStore
collectionT)back_populatesZpassive_deletessessionr   namestrreturnOptional['CollectionStore']c                 C  s   | | | j|k S N)queryfilterr&   first)clsr%   r&   r   r   r    get_by_name2   s   zCollectionStore.get_by_nameN	cmetadataOptional[dict]Tuple['CollectionStore', bool]c                 C  sF   d}|  ||}|r||fS | ||d}|| |  d}||fS )z
        Get or create a collection.
        Returns [Collection, bool] where the bool is True if the collection was created.
        F)r&   r0   T)r/   addcommit)r.   r%   r&   r0   createdr#   r   r   r    get_or_create6   s   
zCollectionStore.get_or_create)r%   r   r&   r'   r(   r)   r*   )r%   r   r&   r'   r0   r1   r(   r2   )r   r   r   r   __tablename__r   r   Stringr&   r   r0   r   
embeddingsclassmethodr/   r6   r   r   r   r    r!   $   s    
r!   c                   @  s   e Zd ZdZdZeeddeje	j dddZ
ee	dd	ZeeejZejejdd
Zejedd
Zejejdd
ZdS )r"   zEmbedding store.Zlangchain_pg_embeddingTr   z.uuidZCASCADE)Zondeleter9   )r$   )ZnullableN)r   r   r   r   r7   r   r   r   Z
ForeignKeyr!   collection_idr   r#   ZARRAYZREAL	embeddingr8   documentr   r0   	custom_idr   r   r   r    r"   M   s    
r"   c                   @  s"   e Zd ZU dZded< ded< dS )QueryResultzResult from a query.r"   floatdistanceN)r   r   r   r   __annotations__r   r   r   r    r?   c   s   
 r?   c                   @  sr  e Zd ZdZedddfdfddZdgddZedhddZdiddZ	dgddZ
dgddZdgddZdgd d!Zd"ed#d$d$fdjd+d,Zdgd-d.Zdkd2d3Zeddedfdld?d@ZdmdBdCZ		dndodEdFZ	G	dpdqdLdMZ	G	dpdrdOdPZ	G	dpdsdRdSZ	G	dpdtdTdUZededdfdudXdYZededdfdvd\d]Zeedfdwd^d_ZedxdadbZeeddfdydddeZdS )zPGEmbeddinga  `Postgres` with the `pg_embedding` extension as a vector store.

    pg_embedding uses sequential scan by default. but you can create a HNSW index
    using the create_hnsw_index method.
    - `connection_string` is a postgres connection string.
    - `embedding_function` any embedding function implementing
        `langchain.embeddings.base.Embeddings` interface.
    - `collection_name` is the name of the collection to use. (default: langchain)
        - NOTE: This is not the name of the table, but the name of the collection.
            The tables will be created when initializing the store (if not exists)
            So, make sure the user has the right permissions to create tables.
    - `distance_strategy` is the distance strategy to use. (default: EUCLIDEAN)
        - `EUCLIDEAN` is the euclidean distance.
    - `pre_delete_collection` if True, will delete the collection if it exists.
        (default: False)
        - Useful for testing.
    NFconnection_stringr'   embedding_functionr   collection_namecollection_metadatar1   pre_delete_collectionboolloggerOptional[logging.Logger]r(   Nonec                 C  s:   || _ || _|| _|| _|| _|ptt| _| 	  d S r*   )
rD   rE   rF   rG   rH   logging	getLoggerr   rJ   __post_init__)selfrD   rE   rF   rG   rH   rJ   r   r   r    __init__}   s   	zPGEmbedding.__init__c                 C  s&   |   | _|   |   |   d S r*   )connect_conncreate_hnsw_extensioncreate_tables_if_not_existscreate_collectionrP   r   r   r    rO      s   
zPGEmbedding.__post_init__c                 C  s   | j S r*   )rE   rW   r   r   r    r9      s   zPGEmbedding.embeddingssqlalchemy.engine.Connectionc                 C  s   t | j}| }|S r*   )r   Zcreate_enginerD   rR   )rP   Zengineconnr   r   r    rR      s   zPGEmbedding.connectc              
   C  s   z(t | j}td}|| |  W d    W d S 1 s!w   Y  W d S  tyA } z| j| W Y d }~d S d }~ww )Nz(CREATE EXTENSION IF NOT EXISTS embedding)	r   rS   r   textexecuter4   	ExceptionrJ   	exception)rP   r%   Z	statementer   r   r    rT      s   


&z!PGEmbedding.create_hnsw_extensionc                 C  >   | j   tj| j  W d    d S 1 sw   Y  d S r*   )rS   beginBasemetadataZ
create_allrW   r   r   r    rU         "z'PGEmbedding.create_tables_if_not_existsc                 C  r_   r*   )rS   r`   ra   rb   Zdrop_allrW   r   r   r    drop_tables   rc   zPGEmbedding.drop_tablesc                 C  sR   | j r|   t| j}tj|| j| jd W d    d S 1 s"w   Y  d S )N)r0   )rH   delete_collectionr   rS   r!   r6   rF   rG   rP   r%   r   r   r    rV      s   
"zPGEmbedding.create_collectioni'        max_elementsintdimsmef_construction	ef_searchc           	   
   C  s   t d|||||}z%t| j}|| |  W d    n1 s&w   Y  td W d S  tyK } ztd|  W Y d }~d S d }~ww )NzCREATE INDEX IF NOT EXISTS langchain_pg_embedding_idx ON langchain_pg_embedding USING hnsw (embedding) WITH (maxelements = {}, dims = {}, m = {}, efconstruction = {}, efsearch = {});z.HNSW extension and index created successfully.z*Failed to create HNSW extension or index: )	r   rZ   formatr   rS   r[   r4   printr\   )	rP   ri   rk   rl   rm   rn   Zcreate_index_queryr%   r^   r   r   r    create_hnsw_index   s   

zPGEmbedding.create_hnsw_indexc                 C  sz   | j d t| j(}| |}|s"| j d 	 W d    d S || |  W d    d S 1 s6w   Y  d S )NzTrying to delete collectionCollection not found)rJ   debugr   rS   get_collectionwarningdeleter4   )rP   r%   r#   r   r   r    re      s   


"zPGEmbedding.delete_collectionr%   r   r)   c                 C  s   t || jS r*   )r!   r/   rF   rf   r   r   r    rt      s   zPGEmbedding.get_collectiontexts	List[str]r9   List[List[float]]r<   	metadatasOptional[List[dict]]idsOptional[List[str]]kwargsr   c                 K  s`   |d u rdd |D }|sdd |D }|  |}	| |	|||d}
|
jd||||d| |
S )Nc                 S     g | ]}t t qS r   r'   r   r   .0_r   r   r    
<listcomp>       z;PGEmbedding._initialize_from_embeddings.<locals>.<listcomp>c                 S     g | ]}i qS r   r   r   r   r   r    r          rD   rF   rE   rH   )rw   r9   rz   r|   r   )get_connection_stringadd_embeddings)r.   rw   r9   r<   rz   r|   rF   rH   r~   rD   storer   r   r    _initialize_from_embeddings   s"   
z'PGEmbedding._initialize_from_embeddings
List[dict]c                 K  s   t | j9}| |}|stdt||||D ]\}}	}
}t|
||	|d}|j| || q|	  W d    d S 1 sAw   Y  d S )Nrr   r<   r=   r0   r>   )
r   rS   rt   
ValueErrorzipr"   r9   appendr3   r4   )rP   rw   r9   rz   r|   r~   r%   r#   rZ   rb   r<   idembedding_storer   r   r    r     s   

"zPGEmbedding.add_embeddingsIterable[str]c                 K  s   |d u rdd |D }| j t|}|sdd |D }t| j9}| |}|s-tdt||||D ]\}}	}
}t|
||	|d}|j	
| || q4|  W d    |S 1 s]w   Y  |S )Nc                 S  r   r   r   r   r   r   r    r   #  r   z)PGEmbedding.add_texts.<locals>.<listcomp>c                 S  r   r   r   r   r   r   r    r   (  r   rr   r   )rE   embed_documentslistr   rS   rt   r   r   r"   r9   r   r3   r4   )rP   rw   rz   r|   r~   r9   r%   r#   rZ   rb   r<   r   r   r   r   r    	add_texts  s.   


zPGEmbedding.add_texts   r+   kr,   List[Document]c                 K  s   | j j|d}| j|||dS )N)rZ   r<   r   r,   )rE   embed_querysimilarity_search_by_vector)rP   r+   r   r,   r~   r<   r   r   r    similarity_search;  s   zPGEmbedding.similarity_searchList[Tuple[Document, float]]c                 C  s    | j |}| j|||d}|S )Nr   )rE   r   &similarity_search_with_score_by_vector)rP   r+   r   r,   r<   docsr   r   r    similarity_search_with_scoreI  s
   z(PGEmbedding.similarity_search_with_scoreList[float]c              	     s  t  j} |}td}|| |stdtj|j	k}|d urg }|
 D ]^\}	}
d}t|
trX|ttj|
v rXdd |

 D }tj|	 j|| }|| q+t|
trzdttj|
v rztj|	 jd|
d  d}|| q+tj|	 jt|
k}|| q+tj|g|R  }|tttjd|d	|ttjd| |  }W d    n1 sw   Y   fd
d|D }|S )NzSET enable_seqscan = offrr   inc                 S  s   i | ]	\}}|  |qS r   )lower)r   r   vr   r   r    
<dictcomp>i  s    zFPGEmbedding.similarity_search_with_score_by_vector.<locals>.<dictcomp>Z	substring%z<->rA   c                   s4   g | ]}t |jj|jjd  jdur|jndfqS ))page_contentrb   Ng        )r   r"   r=   r0   rE   rA   )r   resultrW   r   r    r     s    zFPGEmbedding.similarity_search_with_score_by_vector.<locals>.<listcomp>)!r   rS   rt   r   rZ   r[   r   r"   r;   r   items
isinstancedictmapr'   r   r0   Zastextin_r   Zilikeand_r+   r
   absr<   oplabelr,   Zorder_byasclimitall)rP   r<   r   r,   r%   r#   Zset_enable_seqscan_stmtZ	filter_byZfilter_clauseskeyvalueINZvalue_case_insensitiveZfilter_by_metadataresultsr   r   rW   r    r   U  sf   



3
z2PGEmbedding.similarity_search_with_score_by_vectorc                 K  s   | j |||d}dd |D S )Nr   c                 S  s   g | ]\}}|qS r   r   )r   docr   r   r   r    r         z;PGEmbedding.similarity_search_by_vector.<locals>.<listcomp>)r   )rP   r<   r   r,   r~   Zdocs_and_scoresr   r   r    r     s   z'PGEmbedding.similarity_search_by_vectorr.   Type[PGEmbedding]c           	      K  s.   | t|}| j|||f||||d|S )Nrz   r|   rF   rH   )r   r   r   )	r.   rw   r<   rz   rF   r|   rH   r~   r9   r   r   r    
from_texts  s   zPGEmbedding.from_textstext_embeddingsList[Tuple[str, List[float]]]c           
      K  s<   dd |D }dd |D }	| j ||	|f||||d|S )Nc                 S     g | ]}|d  qS )r   r   r   tr   r   r    r     r   z/PGEmbedding.from_embeddings.<locals>.<listcomp>c                 S  r   )   r   r   r   r   r    r     r   r   )r   )
r.   r   r<   rz   rF   r|   rH   r~   rw   r9   r   r   r    from_embeddings  s   zPGEmbedding.from_embeddingsc                 K  s   |  |}| ||||d}|S )Nr   )r   )r.   r<   rF   rH   r~   rD   r   r   r   r    from_existing_index  s   
zPGEmbedding.from_existing_indexDict[str, Any]c                 C  s   t |ddd}|std|S )NrD   ZPOSTGRES_CONNECTION_STRING)datar   Zenv_keyz~Postgres connection string is requiredEither pass it as a parameteror set the POSTGRES_CONNECTION_STRING environment variable.)r   r   )r.   r~   rD   r   r   r    r     s   z!PGEmbedding.get_connection_string	documentsc           
   	   K  sL   dd |D }dd |D }|  |}	|	|d< | jd||||||d|S )Nc                 S     g | ]}|j qS r   )r   r   dr   r   r    r         z.PGEmbedding.from_documents.<locals>.<listcomp>c                 S  r   r   )rb   r   r   r   r    r     r   rD   )rw   rH   r<   rz   r|   rF   r   )r   r   )
r.   r   r<   rF   r|   rH   r~   rw   rz   rD   r   r   r    from_documents  s   

zPGEmbedding.from_documents)rD   r'   rE   r   rF   r'   rG   r1   rH   rI   rJ   rK   r(   rL   )r(   rL   )r(   r   )r(   rX   )ri   rj   rk   rj   rl   rj   rm   rj   rn   rj   r(   rL   )r%   r   r(   r)   )rw   rx   r9   ry   r<   r   rz   r{   r|   r}   rF   r'   rH   rI   r~   r   r(   rC   )rw   rx   r9   ry   rz   r   r|   rx   r~   r   r(   rL   )NN)
rw   r   rz   r{   r|   r}   r~   r   r(   rx   )r   N)
r+   r'   r   rj   r,   r1   r~   r   r(   r   )r+   r'   r   rj   r,   r1   r(   r   )r<   r   r   rj   r,   r1   r(   r   )
r<   r   r   rj   r,   r1   r~   r   r(   r   )r.   r   rw   rx   r<   r   rz   r{   rF   r'   r|   r}   rH   rI   r~   r   r(   rC   )r   r   r<   r   rz   r{   rF   r'   r|   r}   rH   rI   r~   r   r(   rC   )r.   r   r<   r   rF   r'   rH   rI   r~   r   r(   rC   )r~   r   r(   r'   )r.   r   r   r   r<   r   rF   r'   r|   r}   rH   rI   r~   r   r(   rC   )r   r   r   r   "_LANGCHAIN_DEFAULT_COLLECTION_NAMErQ   rO   propertyr9   rR   rT   rU   rd   rV   ADA_TOKEN_COUNTrq   re   rt   r:   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    rC   j   s    



	






 #HrC   )'
__future__r   rM   r   typingr   r   r   r   r   r   r	   r   r
   Zsqlalchemy.dialects.postgresqlr   r   Zsqlalchemy.ormr   r   r   ImportErrorZsqlalchemy.ext.declarativeZlangchain_core.documentsr   Zlangchain_core.embeddingsr   Zlangchain_core.utilsr   Zlangchain_core.vectorstoresr   ra   r   r   r   r!   r"   r?   rC   r   r   r   r    <module>   s2    $)