
    D6iO)                       d dl mZ d dlZd dlmZmZmZ d dlZd dl	m
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 erd d
lmZ  G d de
      Z G d dej4                  e      Z G d de      Z G d de      Z G d de      Z G d dej                  e   ee      Z G d dee   e      Z 	 dddd	 	 	 	 	 	 	 ddZ!y)    )annotationsN)TYPE_CHECKINGAnycast)Field)Schema
SchemaMeta
SchemaOpts_get_fields   )ModelConverterIncorrectSchemaTypeError)LoadInstanceMixin
_ModelType)DeclarativeMetac                  T     e Zd Zdddd	 	 	 	 	 	 	 d fdZ	 	 	 	 	 	 ddZddZ xZS )	SQLAlchemyAutoFieldN)column_namemodeltablec               x    t         |           |r|rt        d      || _        || _        || _        || _        y )Nz-Cannot pass both `model` and `table` options.)super__init__
ValueErrorr   r   r   field_kwargs)selfr   r   r   r   	__class__s        `/home/azureuser/techstart-app/venv/lib/python3.12/site-packages/marshmallow_sqlalchemy/schema.pyr   zSQLAlchemyAutoField.__init__   s?     	ULMM&

(    c                T   | j                   xs |j                   }|r |j                  ||fi | j                  S | j                  | j                  n|j                  }t	        t        t        j                  |      j                  |      } |j                  |fi | j                  S N)
r   	field_forr   r   getattrr   saTablecolumnscolumn2field)r   schema_optsr   	converterr   r   columns          r   create_fieldz SQLAlchemyAutoField.create_field'   s     

/k//&9&&ukOT=N=NOO"jj4

+:K:Kbhh.66D%y%%fB0A0ABBr    c                     t        d| d      )Nz0Cannot bind SQLAlchemyAutoField. Make sure that z/ is a SQLAlchemySchema or SQLAlchemyAutoSchema.r   )r   
field_nameparents      r   _bind_to_schemaz#SQLAlchemyAutoField._bind_to_schema6   s    &>vhFuv
 	
r    )r   
str | Noner   type[DeclarativeMeta] | Noner   sa.Table | Noner   zdict[str, Any])r)   SQLAlchemySchemaOptsr   strr*   r   )r.   r5   r/   zSchema | FieldreturnNone)__name__
__module____qualname__r   r,   r0   __classcell__r   s   @r   r   r      se     #'.2!%)  ) ,	)
 ) %)$C)C C "	C
r    r   c                  8     e Zd ZU dZded<   ded<    fdZ xZS )r4   a5  Options class for `SQLAlchemySchema`.
    Adds the following options:

    - ``model``: The SQLAlchemy model to generate the `Schema` from (mutually exclusive with ``table``).
    - ``table``: The SQLAlchemy table to generate the `Schema` from (mutually exclusive with ``model``).
    - ``load_instance``: Whether to load model instances.
    - ``sqla_session``: SQLAlchemy session to be used for deserialization.
        This is only needed when ``load_instance`` is `True`. You can also pass a session to the Schema's `load` method.
    - ``transient``: Whether to load model instances in a transient state (effectively ignoring the session).
        Only relevant when ``load_instance`` is `True`.
    - ``model_converter``: `ModelConverter` class to use for converting the SQLAlchemy model to marshmallow fields.
    r3   r   ztype[ModelConverter]model_converterc                    t        |   |g|i | t        |dd       | _        | j                  | j                  t        d      t        |dt              | _        y )Nr   z,Cannot set both `model` and `table` options.r>   )r   r   r$   r   r   r   r   r>   r   metaargskwargsr   s       r   r   zSQLAlchemySchemaOpts.__init__M   s[    ///T7D1
::!djj&<KLL&t->Or    r8   r9   r:   __doc____annotations__r   r;   r<   s   @r   r4   r4   <   s"     ))P Pr    r4   c                  8     e Zd ZU dZded<   ded<    fdZ xZS )SQLAlchemyAutoSchemaOptsa  Options class for `SQLAlchemyAutoSchema`.
    Has the same options as `SQLAlchemySchemaOpts`, with the addition of:

    - ``include_fk``: Whether to include foreign fields; defaults to `False`.
    - ``include_relationships``: Whether to include relationships; defaults to `False`.
    bool
include_fkinclude_relationshipsc                    t        |   |g|i | t        |dd      | _        t        |dd      | _        | j
                  | j                  rt        d      y y )NrJ   FrK   z6Cannot set `table` and `include_relationships = True`.)r   r   r$   rJ   rK   r   r   r@   s       r   r   z!SQLAlchemyAutoSchemaOpts.__init__a   sc    ///!$e<%,T3JE%R"::!d&@&@UVV 'A!r    rD   r<   s   @r   rH   rH   V   s"     W Wr    rH   c                       e Zd Zeef	 	 	 	 	 	 	 d fd       Ze	 	 	 	 	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 	 	 dd       Z	 xZ
S )	SQLAlchemySchemaMetac           	        |j                   }|j                  } ||      }t        	|   ||| j	                  |||      |      }|j                  | j                  ||||             |j                  | j                  ||||             |S )N)
schema_cls)optsklass)rQ   r>   r   get_declared_fields_maybe_filter_foreign_keysupdateget_declared_sqla_fieldsget_auto_fields)
mcsrR   
cls_fieldsinherited_fieldsdict_clsrQ   	Converterr*   fieldsr   s
            r   rS   z(SQLAlchemySchemaMeta.get_declared_fieldsj   s     zz*.*>*>	/	, **+;$e*T
 	c2269dHUVc))&)T8LMr    c                    i S r"    )rX   base_fieldsr*   rQ   r[   s        r   rV   z-SQLAlchemySchemaMeta.get_declared_sqla_fields   s	     	r    c                     ||j                         D ci c]E  \  }}t        |t              r0||j                  vr"||j	                  ||j
                  xs ||      G c}}      S c c}}w r"   )items
isinstancer   excluder,   r   )rX   r]   r*   rQ   r[   r.   fields          r   rW   z$SQLAlchemySchemaMeta.get_auto_fields   su     
 *0	 &Je%89dll2 E..%++9z9 	
 		
s   A
A(
c                 	 |j                   |j                  t        |d      r|j                  du r| S t	        j
                  |j                   xs |j                        j                  D ch c]  }|j                  r|j                   }}t        j                  |      D cg c]$  }t        |t              rt        |t              s|& c}	d	fd}| D cg c]  \  }}||vs ||      r||f c}}S | S c c}w c c}w c c}}w )NrJ   Tc                .     t         fdD              S )Nc           	   3     K   | ]9  }t        t        |d |j                              D cg c]  \  }}|	 c}}v  ; yc c}}w w)_declared_fieldsN)r   r$   __dict__).0basename_re   s       r   	<genexpr>z]SQLAlchemySchemaMeta._maybe_filter_foreign_keys.<locals>.is_declared_field.<locals>.<genexpr>   sW      	   (3#D*<dmmL(#D! 	s   )AA
A)any)re   non_auto_schema_basess   `r   is_declared_fieldzJSQLAlchemySchemaMeta._maybe_filter_foreign_keys.<locals>.is_declared_field   s     	 !6	 	 	r    )re   r5   r6   rI   )r   r   hasattrrJ   r%   inspectr'   foreign_keyskeygetmro
issubclassr   SQLAlchemyAutoSchema)
r]   rQ   rR   r+   ru   rl   rr   rm   re   rq   s
            @r   rT   z/SQLAlchemySchemaMeta._maybe_filter_foreign_keys   s    ::!TZZ%;4.$//T2I !jj)AtzzBJJ&& 

L  $NN51%dF+"4)=> %!
 $*D%|+/@/F u 
 =%&s   /C>')DD)rY   list[tuple[str, Field]]rZ   rz   r[   
type[dict]r6   dict[str, Field])
r`   r|   r*   r   rQ   r   r[   r{   r6   r|   )
r]   r|   r*   r   rQ   r   r[   r{   r6   r|   )r]   rz   rQ   r4   rR   r	   r6   rz   )r8   r9   r:   classmethoddictrS   rV   rW   staticmethodrT   r;   r<   s   @r   rN   rN   i   s     $ , 2	
  
 , % " 	
  
  
 
 "
 	

 
 

 
$ ''' #' 	'
 
!' 'r    rN   c                  "    e Zd Ze	 	 dd       Zy)SQLAlchemyAutoSchemaMetac                    |       }|j                   P|j                  |j                  |j                   |j                  |j                  |j
                  ||             |S |j                  Y|j                  |j                  |j                  |j                  |j                  |j
                  |j                  ||             |S )N)r]   rd   rJ   r`   r[   )r]   rd   rJ   rK   r`   r[   )	r   rU   fields_for_tabler]   rd   rJ   r   fields_for_modelrK   )clsr`   r*   rQ   r[   r]   s         r   rV   z1SQLAlchemyAutoSchemaMeta.get_declared_sqla_fields   s     ::!MM**JJ;; LL# +% + 	,  ZZ#MM**JJ;; LL#*.*D*D +% + 
 r    N)r*   r   )r8   r9   r:   r}   rV   r_   r    r   r   r      s    %3 r    r   c                      e Zd ZdZeZy)SQLAlchemySchemaa  Schema for a SQLAlchemy model or table.
    Use together with `auto_field` to generate fields from columns.

    Example: ::

        from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field

        from mymodels import User


        class UserSchema(SQLAlchemySchema):
            class Meta:
                model = User

            id = auto_field()
            created_at = auto_field(dump_only=True)
            name = auto_field()
    N)r8   r9   r:   rE   r4   OPTIONS_CLASSr_   r    r   r   r      s    & )Mr    r   )	metaclassc                      e Zd ZdZeZy)ry   a  Schema that automatically generates fields from the columns of
     a SQLAlchemy model or table.

    Example: ::

        from marshmallow_sqlalchemy import SQLAlchemyAutoSchema, auto_field

        from mymodels import User


        class UserSchema(SQLAlchemyAutoSchema):
            class Meta:
                model = User
                # OR
                # table = User.__table__

            created_at = auto_field(dump_only=True)
    N)r8   r9   r:   rE   rH   r   r_   r    r   ry   ry     s    & -Mr    ry   )r   r   c               H    | |j                  d|        t        | |||      S )a-  Mark a field to autogenerate from a model or table.

    :param column_name: Name of the column to generate the field from.
        If ``None``, matches the field name. If ``attribute`` is unspecified,
        ``attribute`` will be set to the same value as ``column_name``.
    :param model: Model to generate the field from.
        If ``None``, uses ``model`` specified on ``class Meta``.
    :param table: Table to generate the field from.
        If ``None``, uses ``table`` specified on ``class Meta``.
    :param kwargs: Field argument overrides.
    	attribute)r   r   r   r   )
setdefaultr   )r   r   r   rC   s       r   
auto_fieldr     s0    & +{3uE r    r"   )r   r1   r   r2   r   r3   r6   r   )"
__future__r   rt   typingr   r   r   
sqlalchemyr%   marshmallow.fieldsr   marshmallow.schemar   r	   r
   r   convertr   
exceptionsr   load_instance_mixinr   r   sqlalchemy.ext.declarativer   r   Optsr4   rH   rN   r   r   ry   r   r_   r    r   <module>r      s    "  + +  $ J J # 0 >:
%
% %
PP,11: P4W3 W&]: ]@3 @)Z(&<P)2-Z ,D-4 # +/!	 ( 	 r    