
    D6iYF                    t   U d dl mZ d dl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mZmZ d dlZd dlZd dlmZ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m Z  er,d dl!m"Z" d dl#m$Z$ d dlm%Z% d dl&m'Z' e%ejP                  z  Z)de*d<   eg ejV                  f   Z,de*d<   edege
e-ejV                     e,f   f   Z.de*d<   ddZ/d Z0ddZ1ddZ2	 	 	 	 	 	 ddZ3	 	 	 	 	 	 ddZ4 G d d      Z5 e5       Z6e6jn                  Z7e6jp                  Z8e6jr                  Z9e6jt                  Z:y# e$ r d dlmZmZ Y w xY w)    )annotationsN)TYPE_CHECKINGAnyCallableLiteralUnioncastoverload)	TypeAlias	TypeGuard)fieldsvalidate)mssqlmysql
postgresql)SynonymProperty   )ModelConversionError)RelatedRelatedList)Iterable)DeclarativeMeta)MapperProperty)
TypeEnginer   PropertyOrColumn_FieldPartialModelConverter_FieldClassFactoryc                Z    t        | t              xr t        | t        j                        S N)
isinstancetype
issubclassr   Field)values    a/home/azureuser/techstart-app/venv/lib/python3.12/site-packages/marshmallow_sqlalchemy/convert.py	_is_fieldr'   /   s    eT"Fz%'FF    c                r    | | j                   vr(t        | j                         dk(  r| j                   \  }|S | S )zUnwrap proxied columnsr   )base_columnslen)columnbases     r&   _base_columnr.   3   s9    V(((S1D1D-E-J$$Mr(   c                X    | j                   d uxs | j                  d uxs t        |       S r    )defaultserver_default_is_auto_incrementr,   s    r&   _has_defaultr4   ;   s3    d" 	&  ,	&f%r(   c                R    | j                   d uxr | | j                   j                  u S r    )table_autoincrement_columnr3   s    r&   r2   r2   C   s%    <<t#T&,,2T2T(TTr(   c                t   | j                  |j                        } |       }|j                  r|j                  dk(  r$t        j                  t
        j                  |      S |j                  }t        |dz
        D ]  }t        j                  |      } t        j                  t
        j                  |      S )Nr   )_get_field_class_for_data_type	item_type
dimensions	functoolspartialr   Listrange)	converter	data_type
FieldClassinnerr;   _s         r&   _list_field_factoryrE   G   s     99):M:MNJLE9#7#71#<  e44 %%J:>" #E"# V[[%00r(   c                    |j                   r/t        j                  t        j                  |j                         S t        j
                  S )N)enum)
enum_classr<   r=   r   EnumRaw)r@   rA   s     r&   _enum_field_factoryrK   W   s<    
  	&++I,@,@A ZZr(   c                     e Zd ZU dZi ej
                  eej                  ej                  ej                  eej                  ej                  ej                  ej                  ej                   ej                  ej"                  ej"                  ej$                  ej&                  ej(                  ej&                  ej*                  ej&                  ej                  ej                  ej,                  ej                  ej.                  ej                  ej                  eej0                  ej2                  ej4                  ej6                  ej8                  ej:                  ej                  ej                  ej>                  ej                  ej@                  ejB                  ejD                  ejF                  ejH                  ej                  ejJ                  ejL                  e'j                  ej                  e'jP                  ej"                  iZ)de*d<   ddddZ+d#d$dZ,e-d%d	       Z.ddddde/d
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d&dZ0dddde/d	 	 	 	 	 	 	 	 	 	 	 	 	 d'dZ1e2ddd	 	 	 	 	 	 	 d(d       Z3e2ddd	 	 	 	 	 	 	 d)d       Z3ddd	 	 	 	 	 	 	 d*dZ3e2dd	 	 	 d+d       Z4e2dd	 	 	 d,d       Z4dd	 	 	 d-dZ4e2ddd	 	 	 	 	 	 	 	 	 d.d       Z5e2ddd	 	 	 	 	 	 	 	 	 d/d       Z5ddd	 	 	 	 	 	 	 	 	 d0dZ5d1dZ6d2dZ7	 	 	 	 d3dZ8d4dZ9d5dZ:d6dZ;	 	 	 	 	 	 d7d Z<	 	 d8	 	 	 	 	 	 	 d9d!Z=d" Z>y):r   zxConverts a SQLAlchemy model into a dictionary of corresponding
    marshmallow `Fields <marshmallow.fields.Field>`.
    z?dict[type[TypeEngine], type[fields.Field] | _FieldClassFactory]SQLA_TYPE_MAPPINGFT)	MANYTOONE
MANYTOMANY	ONETOMANYNc                    || _         y r    )
schema_cls)selfrR   s     r&   __init__zModelConverter.__init__   s	    $r(   c                z    | j                   r| j                   j                  S t        j                  j                  S r    )rR   TYPE_MAPPINGmaSchemarS   s    r&   type_mappingzModelConverter.type_mapping   s)    ????///yy%%%r(   )
include_fkinclude_relationshipsr   excludebase_fieldsdict_clsc                   |       }|xs i }t        j                  |      j                  D ]  }	| j                  |	      }
| j	                  |	||      rd||
<   .t        |	t              r?t        |	d      r"|s |	j                  D ]  }|j                  r n m|st        |	d      r||j                  |
      xs | j                  |	      }|s|||
<    |S )a  Generate a dict of field_name: `marshmallow.fields.Field` pairs for the given model.
        Note: SynonymProperties are ignored. Use an explicit field if you want to include a synonym.

        :param model: The SQLAlchemy model
        :param bool include_fk: Whether to include foreign key fields in the output.
        :param bool include_relationships: Whether to include relationships fields in the output.
        :return: dict of field_name: Field instance pairs
        r   r]   Ncolumns	direction)sainspectattrs_get_field_name_should_exclude_fieldr!   r   hasattrrb   foreign_keysgetproperty2field)rS   modelr[   r\   r   r]   r^   r_   resultpropkeyr,   fields                r&   fields_for_modelzModelConverter.fields_for_model   s    & !'RJJu%++ 	$D&&t,C))$vw)O"s$0tY'! #',, !%22!! !(WT;-GOOC(ED,?,?,EE#s+	$, r(   )r[   r   r]   r^   r_   c                   |       }|xs i }|j                   D ]h  }| j                  |      }	| j                  |||      rd ||	<   .|s|j                  r=|j	                  |	      xs | j                  |      }
|
sd|
||	<   j |S )Nra   )rb   rg   rh   rj   rk   column2field)rS   r6   r[   r   r]   r^   r_   rn   r,   rp   rq   s              r&   fields_for_tablezModelConverter.fields_for_table   s     !'Rmm 	$F&&v.C))&)Q"s&"5"5  OOC(ED,=,=f,EE#s	$ r(   .instancefield_classc                    y r     rS   ro   rw   rx   kwargss        r&   rl   zModelConverter.property2field   s     r(   c                    y r    rz   r{   s        r&   rl   zModelConverter.property2field   s     !r(   c               t   dD ]  }t        ||d      }||} |xs | j                  |      }|s|S | j                  |      }|j                  |        |di |}t	        |d      rO| j
                  |j                  j                     r,|j                  du rt        |fi i | j                         |}|S )a  Convert a SQLAlchemy `Property` to a field instance or class.

        :param Property prop: SQLAlchemy Property.
        :param bool instance: If `True`, return  `Field` instance, computing relevant kwargs
            from the given property. If `False`, return the `Field` class.
        :param kwargs: Additional keyword arguments to pass to the field constructor.
        :return: A `marshmallow.fields.Field` class or instance.
        )_proxied_property_proxied_objectNrc   Trz   )getattr_get_field_class_for_property_get_field_kwargs_for_propertyupdateri   DIRECTION_MAPPINGrc   nameuselistr   get_base_kwargs)	rS   ro   rw   rx   r|   attrproxied_objfield_kwargsrets	            r&   rl   zModelConverter.property2field   s    $ = 	#D!$d3K&"	# "MT%G%G%M::4@F#)L)D+&&&t~~':':;$cJ%I(<(<(>%I&%IJC
r(   )rw   c                    y r    rz   rS   r,   rw   r|   s       r&   rt   zModelConverter.column2field  s     r(   c                    y r    rz   r   s       r&   rt   zModelConverter.column2field  s     !r(   c                   | j                  |      }|s|S | j                         }| j                  ||        |di i ||S )a  Convert a SQLAlchemy `Column <sqlalchemy.schema.Column>` to a field instance or class.

        :param sqlalchemy.schema.Column column: SQLAlchemy Column.
        :param bool instance: If `True`, return  `Field` instance, computing relevant kwargs
            from the given property. If `False`, return the `Field` class.
        :return: A `marshmallow.fields.Field` class or instance.
        rz   )_get_field_class_for_columnr   _add_column_kwargs)rS   r,   rw   r|   rx   r   s         r&   rt   zModelConverter.column2field  sT     66v>++-f5877788r(   c                    y r    rz   rS   rm   property_namerw   rx   r|   s         r&   	field_forzModelConverter.field_for*  s     r(   c                    y r    rz   r   s         r&   r   zModelConverter.field_for5  s     !r(   c                  |}|}t        ||      }d}	t        |d      r8|j                  }|j                  }|j                  j
                  j                  }	t        j                  |      j                  j                  |      }
 | j                  |
f|rdnd|d|}|	rt        |fi i | j                         |S |S )a  Convert a property for a mapped SQLAlchemy class to a marshmallow `Field`.
        Example: ::

            date_created = field_for(Author, "date_created", dump_only=True)
            author = field_for(Book, "author")

        :param type model: A SQLAlchemy mapped class.
        :param str property_name: The name of the property to convert.
        :param kwargs: Extra keyword arguments to pass to `property2field`
        :return: A `marshmallow.fields.Field` class or instance.
        Fremote_attrTrv   )r   ri   target_class
value_attr
local_attrro   r   rd   re   rf   rk   rl   r   r   )rS   rm   r   rw   rx   r|   target_model	prop_namer   remote_with_local_multiplicityro   converted_props               r&   r   zModelConverter.field_for@  s    ( !	um,).&4',,LI-1__-A-A-I-I*!zz,7==AA)L,,,
 &T5#	

 
 *~V1UD4H4H4J1Uf1UVVr(   c                    |j                   S r    )rp   )rS   prop_or_columns     r&   rg   zModelConverter._get_field_nameh  s    !!!r(   c                8    | j                  |j                        S r    )r9   r"   )rS   r,   s     r&   r   z*ModelConverter._get_field_class_for_columnk  s    226;;??r(   c                   d }t        j                  t        |            }|D ]F  }|| j                  v s| j                  |   }t	        |      r|}n t        t        |      | |      } ne 	 |j                  }|| j                  v r| j                  |   }n9t        |d      r| j                  |j                        S t        d|d    d      t        t        t        j                     |      S # t        $ r d }Y w xY w)Nimplz$Could not find field column of type r   .)re   getmror"   rM   r'   r	   r   python_typeNotImplementedErrorrZ   ri   r9   r   r   r   r$   )rS   rA   	field_clstypescol_typefield_or_factoryr   s          r&   r9   z-ModelConverter._get_field_class_for_data_typen  s    @D	tI/ 	H4111#'#9#9(#C -. 0I J%79I Ji!I 	#'33 d/// --k:	9f->>y~~NN*:58*AF  D&	22 ' #"#s   -C1 1C?>C?c                    t        |d      rt        }|S t        |j                  d         }| j	                  |      }|S )Nrc   r   )ri   r   r.   rb   r   )rS   ro   r   r,   s       r&   r   z,ModelConverter._get_field_class_for_property  sC    4%I  "$,,q/2F88@Ir(   c                   | j                         }t        |d      r,t        |j                  d         }| j	                  ||       |}t        |d      r| j                  ||       t        |dd       r|j                  |d   d<   |S )Nrb   r   rc   docmetadatadescription)r   ri   r.   rb   r   _add_relationship_kwargsr   r   )rS   ro   r|   r,   s       r&   r   z-ModelConverter._get_field_kwargs_for_property  s    %%'4#!$,,q/2F##FF3D4%))&$74%04F:}-r(   c                   t        |d      r0|j                  rd|d<   |j                   xr t        |       |d<   nd|d<   t        |j                  d      r0|j                  j                  |j                  j                  |d<   nct        |j                  d	      rM|j                  d      s<|d
   j                  t        j                  |j                  j                               t        |j                  d      r|j                  d      ss|j                  j                  }|[	 |j                  j                  }|rt        |t        j                         s(|d
   j                  t        j"                  |             t%        |j                  dd      rt%        |j                  dd      |d<   yy# t        t        f$ r d}Y w xY w)zwAdd keyword arguments to kwargs (in-place) based on the passed in
        `Column <sqlalchemy.schema.Column>`.
        nullableT
allow_nonerequired	dump_onlyrH   NrG   enumsr   )choiceslength)max	asdecimalFscaleplaces)ri   r   r4   r"   rH   rk   appendr   OneOfr   r   r   AttributeErrorr   r#   uuidUUIDLengthr   )rS   r|   r,   column_lengthr   s        r&   r   z!ModelConverter._add_column_kwargs  sr    6:&'+|$%+__!4!Q\&=Q9QF: #'F;6;;-&++2H2H2T#[[33F6NV[['*6::k3J:%%hnnV[[=N=N&OP
 6;;)&**[2I"KK..M('"(++"9"9K #*[$))*L:&--hoo-.PQ6;;U3&v{{GTBF8 4 '(;< '"&K's   +F8 8GGc                    d}|j                   D ]H  }|d   j                  r|j                  du s%| j                  |j                  j
                     du rd} n |j                  || d       y)zkAdd keyword arguments to kwargs (in-place) based on the passed in
        relationship `Property`.
        Tr   F)r   r   N)local_remote_pairsr   r   r   rc   r   r   )rS   r|   ro   r   pairs        r&   r   z'ModelConverter._add_relationship_kwargs  sq     ++ 	D7##LLD(--dnn.A.ABeK$H	 	Xx<HIr(   c                T    | j                  |      }|r||vryt        |xr ||v       S )NT)rg   bool)rS   r,   r   r]   rp   s        r&   rh   z$ModelConverter._should_exclude_field  s5     ""6*c'G.w//r(   c                    g i dS )N)r   r   rz   rY   s    r&   r   zModelConverter.get_base_kwargs  s    B//r(   r    )rR   ztype[ma.Schema] | None)returnzdict[type, type[fields.Field]])rm   type[DeclarativeMeta]r[   r   r\   r   r   Iterable[str] | Noner]   r   r^   dict | Noner_   
type[dict]r   dict[str, fields.Field])r6   zsa.Tabler[   r   r   r   r]   r   r^   r   r_   r   r   r   )ro   r   rw   Literal[True]rx   type[fields.Field] | Noner   fields.Field)ro   r   rw   Literal[False]rx   r   r   type[fields.Field])ro   r   rw   r   rx   r   r   !fields.Field | type[fields.Field])rw   r   r   r   )rw   r   r   r   )rw   r   r   r   )
rm   r   r   strrw   r   rx   r   r   r   )
rm   r   r   r   rw   r   rx   r   r   r   )
rm   r   r   r   rw   r   rx   r   r   r   )r   r   r   r   )r,   	sa.Columnr   r   )rA   r   r   r   )r   r   )ro   r   r   dict[str, Any])r|   r   r,   r   r   None)r|   r   ro   r   r   r   )NN)r,   r   r   r   r]   r   r   r   )?__name__
__module____qualname____doc__rd   rI   rK   JSONr   rJ   ARRAYrE   
PickleTyper   BITIntegerOIDr   MACADDRStringINETCIDRJSONBHSTOREMONEYDecimalDATEDateTIMETimer   YEARSETr>   ENUMr$   INTEGERDATETIMEDateTimer   UNIQUEIDENTIFIERrM   __annotations__r   rT   propertyrZ   dictrr   ru   r
   rl   rt   r   rg   r   r9   r   r   r   r   rh   r   rz   r(   r&   r   r   a   sH   	
$	
	 	%	 	vzz		
 		 		 		 	FMM	 		 		 		 	&**	 	6::	 	-	 	&..	  	!	" 	#	$ 			6>>

FNN		6;;

FLLv~~		6>>3	   : ',4dS% & & !&+'+(,#'#,$, 	,
  $, %, &, !, , 
!,d !'+(,#'# 	
 % & !  
!6 
 #&14  	
 / 
  
 $'14!! !	!
 /! 
! ! 15"" 	"
 /" 
+"H 36#0	  47!#1!	! !
 +/9#'9	*9"  #&14$ 
   / 
   $'15!$! !
 !! /! 
! ! 15&$& &
 & /& 
+&P"@3#3	3B
 CDJ$J,<J	J( (,(,		0 	0 %	0 &		0
 
	00r(   )r%   r   r   zTypeGuard[type[fields.Field]])r   r   )r@   r   rA   zpostgresql.ARRAYr   zCallable[[], fields.List])r@   r   rA   zsa.Enumr   zCallable[[], fields.Field]);
__future__r   r<   re   r   typingr   r   r   r   r   r	   r
   r   r   ImportErrortyping_extensionsmarshmallowrW   
sqlalchemyrd   r   r   sqlalchemy.dialectsr   r   r   sqlalchemy.ormr   
exceptionsr   r   r   collections.abcr   sqlalchemy.ext.declarativer   r   sqlalchemy.typesr   Columnr   r   r$   r   r"   r   r'   r.   r4   r2   rE   rK   r   default_converterrr   rl   rt   r   rz   r(   r&   <module>r     s\   "     7+   ( 8 8 * , ((:-+"0299"<i<#B$45y 5 (sU4#5}#DEE! I 
GU11*:11 *1B0 B0J #$ $55 "11 --''	q  7667s   D& &D76D7