a
    bg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y   d dlmZ Y n0 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   z/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/vectorstores/pgembedding.pyr      s   r   c                   @  sh   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	d
ddZeddddddddZdS )CollectionStorezCollection store.Zlangchain_pg_collectionEmbeddingStore
collectionT)back_populatesZpassive_deletesr   strOptional['CollectionStore'])sessionnamereturnc                 C  s   | | | j|k S N)queryfilterr(   first)clsr'   r(   r   r   r    get_by_name2   s    zCollectionStore.get_by_nameNOptional[dict]zTuple['CollectionStore', bool])r'   r(   	cmetadatar)   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(   r1   T)r/   addcommit)r.   r'   r(   r1   createdr#   r   r   r    get_or_create6   s    
zCollectionStore.get_or_create)N)r   r   r   r   __tablename__r   r   Stringr(   r   r1   r   
embeddingsclassmethodr/   r5   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ondeleter8   )r$   )ZnullableN)r   r   r   r   r6   r   r   r   Z
ForeignKeyr!   collection_idr   r#   ZARRAYZREAL	embeddingr7   documentr   r1   	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                   @  sH  e Zd ZdZedddfddddddd	d
ddZd	dddZeddddZddddZ	d	dddZ
d	dddZd	dddZd	dddZdedddfd d d d d d	d!d"d#Zd	dd$d%Zd&d'd(d)d*Zeddedfd+d,dd-d.ddd/d d0	d1d2Zd+d,d3d+d/d	d4d5d6Zd]d7d-d.d/d+d8d9d:Zd^dd dd/d<d=d>d?Zd_dd dd@dAdBdCZd`dDd dd@dEdFdGZdadDd dd/d<dHdIdJZededdfdKd+dd-dd.dd/d dL	dMdNZededdfdOdd-dd.dd/d dPdQdRZeedfdKdddd/d dSdTdUZedVddWdXdYZeeddfdKd<ddd.dd/d dZd[d\ZdS )b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.
    NFr%   r   r0   boolzOptional[logging.Logger]None)connection_stringembedding_functioncollection_namecollection_metadatapre_delete_collectionloggerr)   c                 C  s:   || _ || _|| _|| _|| _|p*tt| _| 	  d S r*   )
rE   rF   rG   rH   rI   logging	getLoggerr   rJ   __post_init__)selfrE   rF   rG   rH   rI   rJ   r   r   r    __init__}   s    	zPGEmbedding.__init__)r)   c                 C  s&   |   | _|   |   |   d S r*   )connect_conncreate_hnsw_extensioncreate_tables_if_not_existscreate_collectionrN   r   r   r    rM      s    
zPGEmbedding.__post_init__c                 C  s   | j S r*   )rF   rU   r   r   r    r8      s    zPGEmbedding.embeddingszsqlalchemy.engine.Connectionc                 C  s   t | j}| }|S r*   )r   Zcreate_enginerE   rP   )rN   Zengineconnr   r   r    rP      s    zPGEmbedding.connectc              
   C  s   zJt | j,}td}|| |  W d    n1 s>0    Y  W n0 tyz } z| j| W Y d }~n
d }~0 0 d S )Nz(CREATE EXTENSION IF NOT EXISTS embedding)	r   rQ   r   textexecuter3   	ExceptionrJ   	exception)rN   r'   Z	statementer   r   r    rR      s    

*z!PGEmbedding.create_hnsw_extensionc                 C  s<   | j   tj| j  W d    n1 s.0    Y  d S r*   )rQ   beginBasemetadataZ
create_allrU   r   r   r    rS      s    z'PGEmbedding.create_tables_if_not_existsc                 C  s<   | j   tj| j  W d    n1 s.0    Y  d S r*   )rQ   r\   r]   r^   Zdrop_allrU   r   r   r    drop_tables   s    zPGEmbedding.drop_tablesc                 C  sP   | j r|   t| j$}tj|| j| jd W d    n1 sB0    Y  d S )N)r1   )rI   delete_collectionr   rQ   r!   r5   rG   rH   rN   r'   r   r   r    rT      s    
zPGEmbedding.create_collectioni'        int)max_elementsdimsmef_construction	ef_searchr)   c           	   
   C  s   t d|||||}zHt| j"}|| |  W d    n1 sL0    Y  td W n2 ty } ztd|  W Y d }~n
d }~0 0 d S )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   rW   formatr   rQ   rX   r3   printrY   )	rN   re   rf   rg   rh   ri   Zcreate_index_queryr'   r[   r   r   r    create_hnsw_index   s    

&zPGEmbedding.create_hnsw_indexc                 C  sv   | j d t| jL}| |}|sB| j d W d    d S || |  W d    n1 sh0    Y  d S )NzTrying to delete collectionCollection not found)rJ   debugr   rQ   get_collectionwarningdeleter3   )rN   r'   r#   r   r   r    r`      s    

zPGEmbedding.delete_collectionr   r&   )r'   r)   c                 C  s   t || jS r*   )r!   r/   rG   ra   r   r   r    ro      s    zPGEmbedding.get_collectionz	List[str]zList[List[float]]zOptional[List[dict]]zOptional[List[str]]r   )	textsr8   r;   	metadatasidsrG   rI   kwargsr)   c                 K  s`   |d u rdd |D }|s(dd |D }|  |}	| |	|||d}
|
jf ||||d| |
S )Nc                 S  s   g | ]}t t qS r   r%   r   r   .0_r   r   r    
<listcomp>       z;PGEmbedding._initialize_from_embeddings.<locals>.<listcomp>c                 S  s   g | ]}i qS r   r   rw   r   r   r    rz      r{   rE   rG   rF   rI   )rr   r8   rs   rt   )get_connection_stringadd_embeddings)r.   rr   r8   r;   rs   rt   rG   rI   ru   rE   storer   r   r    _initialize_from_embeddings   s"    
z'PGEmbedding._initialize_from_embeddingsz
List[dict])rr   r8   rs   rt   ru   r)   c                 K  s   t | jp}| |}|s"tdt||||D ]2\}}	}
}t|
||	|d}|j| || q0|	  W d    n1 s0    Y  d S )Nrm   r;   r<   r1   r=   )
r   rQ   ro   
ValueErrorzipr"   r8   appendr2   r3   )rN   rr   r8   rs   rt   ru   r'   r#   rW   r^   r;   idembedding_storer   r   r    r~     s    
zPGEmbedding.add_embeddingszIterable[str])rr   rs   rt   ru   r)   c                 K  s   |d u rdd |D }| j t|}|s8dd |D }t| jp}| |}|sZtdt||||D ]2\}}	}
}t|
||	|d}|j	
| || qh|  W d    n1 s0    Y  |S )Nc                 S  s   g | ]}t t qS r   rv   rw   r   r   r    rz   #  r{   z)PGEmbedding.add_texts.<locals>.<listcomp>c                 S  s   g | ]}i qS r   r   rw   r   r   r    rz   (  r{   rm   r   )rF   embed_documentslistr   rQ   ro   r   r   r"   r8   r   r2   r3   )rN   rr   rs   rt   ru   r8   r'   r#   rW   r^   r;   r   r   r   r   r    	add_texts  s(    
&zPGEmbedding.add_texts   zList[Document])r+   kr,   ru   r)   c                 K  s   | j j|d}| j|||dS )N)rW   r;   r   r,   )rF   embed_querysimilarity_search_by_vector)rN   r+   r   r,   ru   r;   r   r   r    similarity_search;  s    zPGEmbedding.similarity_searchzList[Tuple[Document, float]])r+   r   r,   r)   c                 C  s    | j |}| j|||d}|S )Nr   )rF   r   &similarity_search_with_score_by_vector)rN   r+   r   r,   r;   docsr   r   r    similarity_search_with_scoreI  s
    z(PGEmbedding.similarity_search_with_scorezList[float])r;   r   r,   r)   c              	     s  t  j|} |}td}|| |s8tdtj|j	k}|d ur*g }|
 D ]\}	}
d}t|
tr|ttj|
v rdd |

 D }tj|	 j|| }|| qZt|
trdttj|
v rtj|	 jd|
d  d}|| qZtj|	 jt|
k}|| qZtj|g|R  }|tttjd|d	|ttjd| |  }W d    n1 s0    Y   fd
d|D }|S )NzSET enable_seqscan = offrm   inc                 S  s   i | ]\}}|  |qS r   )lower)rx   r   vr   r   r    
<dictcomp>i  s   zFPGEmbedding.similarity_search_with_score_by_vector.<locals>.<dictcomp>Z	substring%z<->r@   c                   s4   g | ],}t |jj|jjd  jdur*|jndfqS ))page_contentr^   Ng        )r   r"   r<   r1   rF   r@   )rx   resultrU   r   r    rz     s   zFPGEmbedding.similarity_search_with_score_by_vector.<locals>.<listcomp>)!r   rQ   ro   r   rW   rX   r   r"   r:   r   items
isinstancedictmapr%   r   r1   ZastextZin_r   Zilikeand_r+   r
   absr;   oplabelr,   Zorder_byasclimitall)rN   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   rU   r    r   U  sd    




"

z2PGEmbedding.similarity_search_with_score_by_vector)r;   r   r,   ru   r)   c                 K  s   | j |||d}dd |D S )Nr   c                 S  s   g | ]\}}|qS r   r   )rx   docry   r   r   r    rz     r{   z;PGEmbedding.similarity_search_by_vector.<locals>.<listcomp>)r   )rN   r;   r   r,   ru   Zdocs_and_scoresr   r   r    r     s    z'PGEmbedding.similarity_search_by_vectorzType[PGEmbedding])	r.   rr   r;   rs   rG   rt   rI   ru   r)   c           	      K  s.   | t|}| j|||f||||d|S )Nrs   rt   rG   rI   )r   r   r   )	r.   rr   r;   rs   rG   rt   rI   ru   r8   r   r   r    
from_texts  s    zPGEmbedding.from_textszList[Tuple[str, List[float]]])text_embeddingsr;   rs   rG   rt   rI   ru   r)   c           
      K  s<   dd |D }dd |D }	| j ||	|f||||d|S )Nc                 S  s   g | ]}|d  qS )r   r   rx   tr   r   r    rz     r{   z/PGEmbedding.from_embeddings.<locals>.<listcomp>c                 S  s   g | ]}|d  qS )   r   r   r   r   r    rz     r{   r   )r   )
r.   r   r;   rs   rG   rt   rI   ru   rr   r8   r   r   r    from_embeddings  s    zPGEmbedding.from_embeddings)r.   r;   rG   rI   ru   r)   c                 K  s   |  |}| ||||d}|S )Nr|   )r}   )r.   r;   rG   rI   ru   rE   r   r   r   r    from_existing_index  s    
zPGEmbedding.from_existing_indexzDict[str, Any])ru   r)   c                 C  s   t |ddd}|std|S )NrE   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.   ru   rE   r   r   r    r}     s    z!PGEmbedding.get_connection_string)r.   	documentsr;   rG   rt   rI   ru   r)   c           
   	   K  sL   dd |D }dd |D }|  |}	|	|d< | jf ||||||d|S )Nc                 S  s   g | ]
}|j qS r   )r   rx   dr   r   r    rz     r{   z.PGEmbedding.from_documents.<locals>.<listcomp>c                 S  s   g | ]
}|j qS r   )r^   r   r   r   r    rz     r{   rE   )rr   rI   r;   rs   rt   rG   )r}   r   )
r.   r   r;   rG   rt   rI   ru   rr   rs   rE   r   r   r    from_documents  s    

zPGEmbedding.from_documents)NN)r   N)r   N)r   N)r   N)r   r   r   r   "_LANGCHAIN_DEFAULT_COLLECTION_NAMErO   rM   propertyr8   rP   rR   rS   r_   rT   ADA_TOKEN_COUNTrl   r`   ro   r9   r   r~   r   r   r   r   r   r   r   r   r}   r   r   r   r   r    rB   j   s   	

"   #      H  " rB   )'
__future__r   rK   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   r]   r   r   r   r!   r"   r>   rB   r   r   r   r    <module>   s.   $)