o
    KDi                     @  s   d dl mZ d dl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 er:d dlmZ d d	lmZ G d
d dejZG dd dejZG dd dejZdddZdddZdS )    )annotationsN)TYPE_CHECKINGAnycast)fields)is_iterable_but_not_string)inspect)NoResultFound)DeclarativeMeta)MapperPropertyc                      s   e Zd Zd fdd	Z  ZS )RelatedListNc                   s   t tj| j|||dS )N)accessor)superr   List	get_value)selfobjattrr   	__class__ V/var/www/Datamplify/venv/lib/python3.10/site-packages/marshmallow_sqlalchemy/fields.pyr      s   zRelatedList.get_valueN)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s    r   c                      s   e Zd ZdZddiZ		dd fd	d
Zed ddZed!ddZedd Z	edd Z
edd Zdd Zdd Zdd Z  ZS )"Relateda~  Related data represented by a SQLAlchemy `relationship`. Must be attached
    to a `Schema <marshmallow.Schema>` class whose options includes a SQLAlchemy `model`, such
    as `SQLAlchemySchema <marshmallow_sqlalchemy.SQLAlchemySchema>`.

    :param columns: Optional column names on related model. If not provided,
        the primary key(s) of the related model will be used.
    invalidzWCould not deserialize related value {value!r}; expected a dictionary with keys {keys!r}Ncolumnslist[str] | str | Nonecolumn
str | Nonec                   sH   |d urt jdtdd |d u r|}t jdi | t|pg | _d S )Nz_`column` parameter is deprecated and will be removed in future releases. Use `columns` instead.   )
stacklevelr   )warningswarnDeprecationWarningr   __init__ensure_listr   )r   r   r!   kwargsr   r   r   r(   '   s   zRelated.__init__returntype[DeclarativeMeta] | Nonec                 C  s   | j d u r	td| j jjS )Nz4Cannot access model before field is bound to schema.)rootRuntimeErroroptsmodelr   r   r   r   r0   9   s   

zRelated.modeltype[DeclarativeMeta]c                 C  sF   | j d u r	tdt| j td| jp| j}t|dr|j}|jj	j
S )Nz<Cannot access related_model if schema does not have a model.strremote_attr)r0   r.   getattrr   	attributenamehasattrr4   propertymapperclass_)r   
model_attrr   r   r   related_model?   s   


zRelated.related_modelc                   s.   | j rt| j  fdd| j D S t| jS )Nc                   s   g | ]} j | qS r   )attrs.0r!   inspr   r   
<listcomp>N       z(Related.related_keys.<locals>.<listcomp>)r   r   r=   get_primary_keysr1   r   rA   r   related_keysJ   s   

zRelated.related_keysc                 C     | j jS r   )r-   sessionr1   r   r   r   rH   Q      zRelated.sessionc                 C  rG   r   )r-   	transientr1   r   r   r   rJ   U   rI   zRelated.transientc                   s4    fdd| j D }t|dkr|S tt| S )Nc                   s   i | ]}|j t |j d qS r   )keyr5   r@   propvaluer   r   
<dictcomp>Z   s    z&Related._serialize.<locals>.<dictcomp>   )rF   lennextitervalues)r   rO   r   r   retr   rN   r   
_serializeY   s    zRelated._serializec                 O  s   t |ts$t| jdkrdd | jD }| jd||d| jd j|i}| jr/| jdi |S z
| | j|}W |S  t	yJ   | jdi | Y S w )	a  Deserialize a serialized value to a model instance.

        If the parent schema is transient, create a new (transient) instance.
        Otherwise, attempt to find an existing instance in the database.
        :param value: The value to deserialize.
        rQ   c                 S     g | ]}|j qS r   rK   rL   r   r   r   rC   f       z(Related._deserialize.<locals>.<listcomp>r   rO   keysr   Nr   )

isinstancedictrR   rF   
make_errorrK   rJ   r=   _get_existing_instancer	   )r   rO   argsr*   r\   resultr   r   r   _deserialize]   s   
zRelated._deserializec              
     s   | j r| j|jd	i  fdd| jD  }|S  fdd| jD }z	| j||}W n tyK } zdd | jD }| jd |d|d}~ww |du rRt	|S )
a  Retrieve the related object from an existing instance in the DB.

        :param related_model: The related model to query
        :param value: The serialized value to mapto an existing instance.
        :raises NoResultFound: if there is no matching record.
        c                   s   i | ]
}|j  |j qS r   )rK   getrL   rN   r   r   rP   ~   s    z2Related._get_existing_instance.<locals>.<dictcomp>c                   s   g | ]}  |jqS r   )rd   rK   rL   rN   r   r   rC      s    z2Related._get_existing_instance.<locals>.<listcomp>c                 S  rX   r   rY   rL   r   r   r   rC      rZ   r   r[   Nr   )
r   rH   query	filter_byrF   onerd   	TypeErrorr_   r	   )r   r=   rO   rb   lookup_valueserrorr\   r   rN   r   r`   s   s(   
zRelated._get_existing_instance)NN)r   r    r!   r"   )r+   r,   )r+   r2   )r   r   r   __doc__default_error_messagesr(   r9   r0   r=   rF   rH   rJ   rW   rc   r`   r   r   r   r   r   r      s(    	



r   c                      s    e Zd ZdZ fddZ  ZS )Nestedz7Nested field that inherits the session from its parent.c                   s6   t | jdr| jj| j_| jj| j_t j|i |S )NrH   )r8   schemar-   rH   rJ   r   rc   )r   ra   r*   r   r   r   rc      s   zNested._deserialize)r   r   r   rk   rc   r   r   r   r   r   rm      s    rm   r0   r2   r+   list[MapperProperty]c                   s   | j   fdd jD S )zaGet primary key properties for a SQLAlchemy model.

    :param model: SQLAlchemy model class
    c                   s   g | ]}  |qS r   )get_property_by_columnr?   r:   r   r   rC      rD   z$get_primary_keys.<locals>.<listcomp>)
__mapper__primary_key)r0   r   rq   r   rE      s   rE   rO   r   listc                 C  s   t | rt| S | gS r   )r   rt   rN   r   r   r   r)      s   r)   )r0   r2   r+   ro   )rO   r   r+   rt   )
__future__r   r%   typingr   r   r   marshmallowr   marshmallow.utilsr   
sqlalchemyr   sqlalchemy.orm.excr	   sqlalchemy.ext.declarativer
   sqlalchemy.ormr   r   r   Fieldr   rm   rE   r)   r   r   r   r   <module>   s    	v

	