
    gPH                        d dl Z d dlZd dlmZmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZmZmZ d dlmZ  G d d edd            Z G d d      Z y)    N)defaultdict
namedtuple)Enum)TopologicalSorter)chain)settings)models)
operations)	Migration)AlterModelOptions)MigrationOptimizer)MigrationQuestioner)COMPILED_REGEX_TYPERegexObjectresolve_relation)cached_propertyc                   B    e Zd Z G d de      Zed        Zed        Zy)OperationDependencyc                        e Zd ZdZdZdZdZdZy)OperationDependency.Typer               N)__name__
__module____qualname__CREATEREMOVEALTERREMOVE_ORDER_WRTALTER_FOO_TOGETHER     y/var/www/python.vincentserveurtest.ovh/public_html/venv/lib/python3.12/site-packages/django/db/migrations/autodetector.pyTyper      s    r$   r&   c                 6    | j                   j                         S N)
model_namelowerselfs    r%   model_name_lowerz$OperationDependency.model_name_lower!       $$&&r$   c                 6    | j                   j                         S r(   )
field_namer*   r+   s    r%   field_name_lowerz$OperationDependency.field_name_lower%   r.   r$   N)r   r   r   r   r&   r   r-   r1   r#   r$   r%   r   r      s6    t  ' ' ' 'r$   r   z$app_label model_name field_name typec                   `   e Zd ZdZd4dZd5dZd Zd Zd6dZd Z	d	 Z
ed
        Zd4dZd Zd Zd Zd7dZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d  Z"d! Z#d" Z$d# Z%ed$        Z&d% Z'd& Z(d' Z)d( Z*d) Z+d* Z,d+ Z-d, Z.d- Z/d. Z0d/ Z1d0 Z2d4d1Z3d2 Z4e5d3        Z6y)8MigrationAutodetectora  
    Take a pair of ProjectStates and compare them to see what the first would
    need doing to make it match the second (the second usually being the
    project's current state).

    Note that this naturally operates on entire projects at a time,
    as it's likely that changes interact (for example, you can't
    add a ForeignKey without having a migration to add the table it
    depends on first). A user interface may offer single-app usage
    if it wishes, with the caveat that it may not always be possible.
    Nc                     || _         || _        |xs
 t               | _        |j                  D ch c]  \  }}|	 c}}| _        y c c}}w r(   )
from_stateto_stater   
questionerr	   existing_apps)r,   r5   r6   r7   appmodels         r%   __init__zMigrationAutodetector.__init__7   sF    $ $=(;(=4>4E4EF4Ejc5c4EFFs   Ac                 x    | j                  ||      }| j                  |||      }|r| j                  ||      }|S )z
        Main entry point to produce a list of applicable changes.
        Take a graph to base names on and an optional set of apps
        to try and restrict to (restriction is not guaranteed)
        )_detect_changesarrange_for_graph_trim_to_apps)r,   graphtrim_to_appsconvert_appsmigration_namechangess         r%   rD   zMigrationAutodetector.changes=   sD     &&|U;((%H((,?Gr$   c           
          t        |t              r|D cg c]  } j                  |       c}S t        |t              rt         fd|D              S t        |t              r3|j                         D ci c]  \  }}| j                  |       c}}S t        |t        j                        rA|j                   j                  |j                         j                  |j                        fS t        |t              rt        |      S t        |t              r|S t        |d      r|j                         }t        |t         j"                        r|dd }|\  }}}||D cg c]  } j                  |       c}|j                         D ci c]  \  }}| j                  |       c}}fS |S c c}w c c}}w c c}w c c}}w )z
        Recursive deconstruction for a field and its arguments.
        Used for full comparison for rename/alter; sometimes a single-level
        deconstruction will not compare correctly.
        c              3   @   K   | ]  }j                  |        y wr(   )deep_deconstruct).0valuer,   s     r%   	<genexpr>z9MigrationAutodetector.deep_deconstruct.<locals>.<genexpr>R   s     G3%..u53s   deconstructr   N)
isinstancelistrG   tupledictitems	functoolspartialfuncargskeywordsr   r   typehasattrrK   r	   Field)r,   objrI   keydeconstructedpathrT   kwargss   `       r%   rG   z&MigrationAutodetector.deep_deconstructI   s    c4 >ABcUD))%0cBBU#G3GGGT"HK		T*#uC..u55TTY../%%chh/%%cll3 
 01s##T" JS-(OO-M#v||, -ab 1!.D$;?@4%&&u-4@EK\\^T^zsEd++E22^T  J; C U* ATs   F68F;&GG
c                     g }t        |j                               D ]^  \  }}| j                  |      }|j                  r+|j                  j                  r|d   j                  dd       |j                  |       ` |S )z
        Return a definition of the fields that ignores field names and
        what related fields actually relate to. Used for detecting renames (as
        the related fields change during renames).
        r   toN)sortedrP   rG   remote_fieldr:   popappend)r,   fields
fields_defnamefielddeconstructions         r%   only_relation_agnostic_fieldsz3MigrationAutodetector.only_relation_agnostic_fieldso   st     
!&,,.1KD%!2259N!!e&8&8&>&>q!%%dD1n-	 2
 r$   c                 ~   i | _         i | _        i | _        i | _        t	               | _        t	               | _        t	               | _        t	               | _        t	               | _	        t	               | _
        | j                  j                  j                         D ]  \  \  }}}|j                  j                  dd      s| j                  j!                  ||f       C|| j                  j"                  vs\|j                  j                  d      r| j                  j!                  ||f       | j
                  j!                  ||f        | j$                  j                  j                         D ]  \  \  }}}|j                  j                  dd      s| j                  j!                  ||f       C|| j                  j"                  vs|s^||v sc|j                  j                  d      r| j                  j!                  ||f       | j                  j!                  ||f        | j                  j'                          | j$                  j'                          | j)                          | j+                          | j-                          | j/                          | j1                          | j3                          | j5                          | j7                          | j9                          | j;                          | j=                          | j?                          | jA                          | jC                          | jE                          | jG                          | jI                          | jK                          | jM                          | jO                          | jQ                          | jS                          | jU                          | jW                          | jY                          | j[                          | j]                          | j_                  |       | ja                          | jb                  S )aX  
        Return a dict of migration plans which will achieve the
        change from from_state to to_state. The dict has app labels
        as keys and a list of migrations as values.

        The resulting migrations aren't specially named, but the names
        do matter for dependencies inside the set.

        convert_apps is the list of apps to convert to use migrations
        (i.e. to make initial migrations for, in the usual case)

        graph is an optional argument that, if provided, can help improve
        dependency generation and avoid potential circular dependencies.
        managedTproxy)2generated_operationsaltered_indexesaltered_constraintsrenamed_fieldssetold_model_keysold_proxy_keysold_unmanaged_keysnew_model_keysnew_proxy_keysnew_unmanaged_keysr5   r	   rP   optionsgetadd	real_appsr6   resolve_fields_and_relationsgenerate_renamed_models_prepare_field_lists_generate_through_model_mapgenerate_deleted_modelsgenerate_created_modelsgenerate_deleted_proxiesgenerate_created_proxiesgenerate_altered_optionsgenerate_altered_managers!generate_altered_db_table_commentcreate_renamed_fieldscreate_altered_indexescreate_altered_constraintsgenerate_removed_constraintsgenerate_removed_indexesgenerate_renamed_fieldsgenerate_renamed_indexes(generate_removed_altered_unique_togethergenerate_removed_fieldsgenerate_added_fieldsgenerate_altered_fields&generate_altered_order_with_respect_to generate_altered_unique_togethergenerate_added_indexesgenerate_added_constraintsgenerate_altered_db_table_sort_migrations_build_migration_list_optimize_migrations
migrations)r,   rB   r@   	app_labelr)   model_states         r%   r=   z%MigrationAutodetector._detect_changes}   s`   & %'!!#%   "e!e"%%!e!e"%%48OO4J4J4P4P4R0#Y
[&&**9d;''++Y
,CD$//";";;&&**73''++Y
,CD''++Y
,CD 5S 59MM4H4H4N4N4P0#Y
[&&**9d;''++Y
,CD$//";";;l!:&&**73''++Y
,CD''++Y
,CD 5Q 	446224 	$$& 	!!#((* 	$$&$$&%%'%%'%%'&&(..0 	""$ 	##%'')))+%%'$$&%%'557$$&""$$$&335--/##%'')&&(""5)!!#r$   c                 f   | j                   | j                  z  | _        | j                  | j                  z  | _        | j                  | j                  z  | _        i | _	        | j                  D ch c]P  \  }}| j                  j                  || j                  j                  ||f|      f   j                  D ]  }|||f	 R c}}}| _        | j                  D ch c]4  \  }}| j                   j                  ||f   j                  D ]  }|||f	 6 c}}}| _        yc c}}}w c c}}}w )z
        Prepare field lists and a list of the fields that used through models
        in the old state so dependencies can be made from the through model
        deletion to the field that uses it.
        N)rr   ru   kept_model_keysrs   rv   kept_proxy_keysrt   rw   kept_unmanaged_keysthrough_usersr5   r	   renamed_modelsry   rd   old_field_keysr6   new_field_keysr,   r   r)   r0   s       r%   r~   z*MigrationAutodetector._prepare_field_lists   s8     $22T5H5HH#22T5H5HH#'#:#:T=T=T#T  *.)=)=
)=%	:"oo444..22Iz3JJWWf
 
J/ 0)=
 *.)=)=
)=%	:"mm229j3HIPP
 
J/P 0)=


s   2AD%!9D,c                    t        | j                        D ]  \  }}| j                  j                  ||f|      }| j                  j
                  ||f   }|j                  j                         D ]]  \  }}t        |d      st        |j                  dd      s+t        |j                  j                  ||      }|||f| j                  |<   _  y)zThrough model map generation.ra   throughN)r`   rr   r   ry   r5   r	   rd   rP   rW   getattrra   r   r   r   )r,   r   r)   old_model_nameold_model_stater0   rg   through_keys           r%   r   z1MigrationAutodetector._generate_through_model_map   s    %+D,?,?%@!Iz!0044J'N #oo44Y5NOO%4%;%;%A%A%C!
E5.1g&&	47 #3**22Iz#K "&"7D&&{3 &D &Ar$   c                     | j                   dk7  r| dfS t        t        | j                        j	                  d      \  }}t        ||j                         | j                  | j                        dfS )zp
        Return the resolved dependency and a boolean denoting whether or not
        it was swappable.
        __setting__F.T)	r   r   r   r)   splitr   r*   r0   rV   )
dependencyresolved_app_labelresolved_object_names      r%   _resolve_dependencyz)MigrationAutodetector._resolve_dependency  s|     =0u$$3:j++4

%* 	10  "$**,%%	 
 	
r$   c           
         i | _         t        d | j                  j                         D              }d}|r#t	        | j                        D ]  }g }t               }t        | j                  |         D ]  }d}t               }	|j                  D ]a  }
|
}| j                  |
      \  }
}|
j                  |k7  s*| j                  j                  |
j                  g       D ]  }| j                  ||
      sd} n |s n|r(|	j                  |j                  |j                  f       |
j                  | j                   v rB|	j                  |
j                  | j                   |
j                     d   j                  f       |rk|rJ|j                  |
j                        r/|	j                  |j                  |
j                        d          A|	j                  |
j                  df       `d}d |r4|j!                  |       |j#                  |	       | j                  |   d=  n |s|s| j                  |   r|rt%        dt&        fg g d      } |d	t)        | j                   j                  |g             d
z   z  |      }t        |      |_        ||_        || j.                  v|_        | j                   j3                  |g       j!                  |       d}|| j                  |   z   | j                  |<    t        d | j                  j                         D              }||k(  r|sd}nt5        d| j                  z        |}|r"yy)ag  
        Chop the lists of operations up into migrations with dependencies on
        each other. Do this by going through an app's list of operations until
        one is found that has an outgoing dependency that isn't in another
        app's migration yet (hasn't been chopped off its list). Then chop off
        the operations before it into a migration and move onto the next app.
        If the loops completes without doing anything, there's a circular
        dependency (which _should_ be impossible as the operations are
        all split at this point so they can't depend and be depended on).
        c              3   2   K   | ]  }t        |        y wr(   lenrH   xs     r%   rJ   z>MigrationAutodetector._build_migration_list.<locals>.<genexpr>2  s     I&Hc!f&H   FTr   	__first__r   )r
   dependencieszauto_%ir   c              3   2   K   | ]  }t        |        y wr(   r   r   s     r%   rJ   z>MigrationAutodetector._build_migration_list.<locals>.<genexpr>  s     Q.Pc!f.Pr   z)Cannot resolve operation dependencies: %rN)r   sumrm   valuesr`   rq   rM   
_auto_depsr   r   ry   check_dependencyrz   r)   rf   
leaf_nodesrc   updaterV   r   r   r   r
   r8   initial
setdefault
ValueError)r,   r@   num_ops	chop_moder   choppedr   	operationdeps_satisfiedoperation_dependenciesdeporiginal_depis_swappable_depother_operationsubclassinstancenew_num_opss                    r%   r   z+MigrationAutodetector._build_migration_list&  sA    Id&?&?&F&F&HII	 $D$=$=>	"u!%d&?&?	&J!KI%)N-0U*(33
 (+040H0H0M--==I5 483L3L3P3P #r4 $(#8#8##N5:N$)4 $2 %#3$:$>$>,8,B,B,8,C,C)*%& &)]]doo%E$:$>$>,/MM,0OOCMM,J2,N,S,S)*%& (1 ,1U5E5Ecmm5T,B,F,F050@0@0OPQ0R-. -C,F,F140L-. :?m  4n &y1$++,BC 55i@C "LB  744Y?9#''&L+-rB$
 $,%T__-@-@B-O)PST)TU%$ 15\0B-.5++4D<N<N+N(229bAHHR$)	 $d&?&?	&JJ 11)<k ?p Qd.G.G.N.N.PQQKg%  $I$C334  "GQ r$   c                     t         j                  j                               D ]  \  }}t               }|D ]e  }|j	                  |       |j
                  D ]C   j                        d   j                  |k7  r' |j                  |g fd|D          E g t        |j                                j                  |<    y)z{
        Reorder to make things possible. Reordering may be needed so FKs work
        nicely inside the same app.
        r   c              3   H   K   | ]  }j                  |      s|  y wr(   )r   )rH   r   r   r,   s     r%   rJ   z9MigrationAutodetector._sort_migrations.<locals>.<genexpr>  s!      QCq43H3HC3PCs   ""N)
r`   rm   rP   r   rz   r   r   r   rM   static_order)r,   r   opstsopr   s   `    @r%   r   z&MigrationAutodetector._sort_migrations  s    
 %T%>%>%D%D%FGNIs"$Br
==C 2237:C}}	1 BFF2R QC QR )  488I3JD%%i0 Hr$   c                    | j                   j                         D ]C  \  }}t        ||dd        D ],  \  }}|j                  j	                  ||j
                  f       . E | j                   j                         D ],  }|D ]%  }t        t        |j                              |_        ' . | j                   j                         D ]5  \  }}|D ]+  }t               j                  |j                  |      |_        - 7 y )Nr   )r   rP   zipr   rc   rf   r   rM   rq   r   optimizer
   )r,   r   r   m1m2	migrations         r%   r   z*MigrationAutodetector._optimize_migrations  s    %)__%:%:%<!Izj*QR.9B&&	277';< : &=
 //002J'	)-c)2H2H.I)J	& ( 3
 &*__%:%:%<!Iz'	'9';'D'D(()(	$ ( &=r$   c                    j                   \j                  t        j                  j                  k(  r5t        |t        j                        xr |j                  j                  k(  S j                   Ήj                  t        j                  j                  k(  rt        |t        j                        xr9 |j                  j                  k(  xr t        fd|j                  D              xsP t        |t        j                        xr4 |j                  j                  k(  xr |j                  j                  k(  S j                   wj                  t        j                  j                  k(  rPt        |t        j                        xr4 |j                  j                  k(  xr |j                  j                  k(  S j                   \j                  t        j                  j                  k(  r5t        |t        j                         xr |j                  j                  k(  S j                   wj                  t        j                  j"                  k(  rPt        |t        j$                        xr4 |j                  j                  k(  xr |j                  j                  k(  S j                   j                  t        j                  j&                  k(  rbt        |t        j(                        xrF |j                  j                  k(  xr+ |j*                  xs dj-                         j                  k7  S j                   lj                  t        j                  j.                  k(  rEt        |t        j0                  t        j2                  f      xr |j                  j                  k(  S t5        d      )zn
        Return True if the given operation depends on the given dependency,
        False otherwise.
        c              3   B   K   | ]  \  }}j                   |k(    y wr(   )r0   )rH   r   yr   s      r%   rJ   z9MigrationAutodetector.check_dependency.<locals>.<genexpr>  s#     P?Otq!
--2?Os    zCan't handle dependency )r0   rV   r   r&   r   rL   r
   CreateModel
name_lowerr-   anyrd   AddFieldr1   r   RemoveFieldDeleteModelr    
AlterFieldr!   AlterOrderWithRespectToorder_with_respect_tor*   r"   AlterUniqueTogetherAlterIndexTogetherr   )r,   r   r   s     `r%   r   z&MigrationAutodetector.check_dependency  sN    !!)#6#;#;#B#BB 9j&<&<= H((J,G,GG !!-#6#;#;#B#BB 9j&<&<= Q((J,G,GGQPy?O?OPP
 9j&9&9: H..*2M2MMH((J,G,GG !!-#6#;#;#B#BB 9j&<&<= H..*2M2MMH((J,G,GG !!)#6#;#;#B#BB 9j&<&<= H((J,G,GG !!-#6#;#;#A#AA 9j&;&;< H..*2M2MMH((J,G,GG !!-#6#;#;#L#LL 9j&H&HI /((J,G,GG/44:AAC../ !!-#6#;#;#N#NN 33Z5R5RS H ((J,G,GG ZIJJr$   c                     |xs g |_         |r-| j                  j                  |g       j                  d|       y | j                  j                  |g       j	                  |       y )Nr   )r   rm   r   insertrc   )r,   r   r   r   	beginnings        r%   add_operationz#MigrationAutodetector.add_operation  sX      ,1r	%%00B?FFq)T%%00B?FFyQr$   c                    	 | j                   j                  |   }|j                  D ch c]   }t        |t              r|n|j
                  " }}|d   d|d   }|j                  j                  d      s7d|v s3d|v s/t        j                  j                         |j                         k(  rd|d   z   d|d   z   fS 	 |S c c}w # t        $ r Y |S w xY w)z|
        Place potential swappable models first in lists of created models (only
        real way to solve #22783).
        r   r   r   	swappableAbstractUserAbstractBaseUser___)r6   r	   basesrL   strr   rx   ry   r   AUTH_USER_MODELr*   LookupError)r,   itemr   base
base_namesstring_versions         r%   swappable_first_keyz)MigrationAutodetector.swappable_first_key  s    
	--..t4K (---D #4-4==@-   )-Qa9N##''4!Z/%3++113~7K7K7MMQa99 N
   		s#   'C %CA0C C 	CCc                    i | _         i | _        | j                  | j                  z
  }t	        |      D ]K  \  }}| j
                  j                  ||f   }| j                  |j                        }| j                  | j                  z
  }|D ]  \  }}||k(  s| j                  j                  ||f   }	| j                  |	j                        }
||
k(  sI| j                  j                  |	|      sfg }t        |j                  j                               | j
                  j                  ||f   j                         D cg c]#  }|j                         D ]  }|j                   % c}}z   }|D ]<  }|j                   s|j#                  | j%                  |||| j
                               > | j'                  |t)        j*                  |	j,                  |j,                        |       || j                   ||f<   |	j.                  d|	j0                  }|j.                  d|j0                  | j                  |<   | j                  j3                  ||f       | j                  j5                  ||f        K N yc c}}w )z
        Find any renamed models, generate the operations for them, and remove
        the old entry from the model lists. Must be run before other
        model-level generation.
        )old_namenew_namer   r   N)r   renamed_models_relru   rr   r`   r6   r	   ri   rd   r5   r7   ask_rename_modelrM   r   	relationsra   is_relationextend!_get_dependencies_for_foreign_keyr   r
   RenameModelrf   r   r   removerz   )r,   added_modelsr   r)   r   model_fields_defremoved_modelsrem_app_labelrem_model_namerem_model_staterem_model_fields_defr   r  rg   rd   renamed_models_rel_keys                   r%   r}   z-MigrationAutodetector.generate_renamed_models6  s    !"$**T-@-@@%+L%9!Iz--..y*/DEK#AA+BTBTU!0043F3FFN1?-~ I-&*oo&<&<%~5'O ,0+M+M'..,( (+????;;+[ ,.L%)+*<*<*C*C*E%F151H1H$-z$92""(&(2+J2+I .7-=-=-?E	 !& 2 2 .@	 !32+J &F *0#(#4#4$0$7$7(,(N(N,5,6,1,0MM	)*%& *0 !.. ) * 6 6-<-A-A-8-=-=!" .: /  JXD//	:0EF / 9 9 / : :62 %0$9$9$/$:$:!" !334JK !//66~7VW //33Y
4KL!i 2@ &:$Js   (Jc                    | j                   | j                  z  }| j                  |z
  }| j                  |z
  }t	        t        || j                  d      t        || j                  d            }|D ]  \  }}| j                  j                  ||f   }i }d}	|j                  j                         D ]  \  }
}|j                  s|j                  j                  r>|j                  r|j                  j                  }	n|j                  j                  s|||
<   t        |j                  dd      s|||
<    |j                   j#                  d      }|j                   j#                  d      }|j                   j#                  dd      }|j                   j#                  dd      }t%        ||dt$        j&                  j(                        g}|j*                  D ]:  }t-        |t.              sd	|v s|j1                  d	d
      \  }}|j3                  t%        ||dt$        j&                  j4                               | j6                  j                  j9                  ||f      }| j                  j                  j9                  ||f      }|s|st;        |j                        j=                  |j                        j?                  |j                        }|D ]7  }|j3                  t%        |||t$        j&                  j(                               9 = |	rA|j3                  t%        g tA        |	||      dt$        j&                  j4                          | jC                  |tE        jF                  |jH                  |j                  j                         D cg c]  }|d   |vr| c}|j                   |j*                  |jJ                        |d       |j                   j9                  dd      st        |j                               D ]  \  }}| jM                  |||| j                        }|j3                  t%        ||dt$        j&                  j4                               | jC                  |tE        jN                  |||      tQ        t;        |                    |rs| jC                  |tE        jR                  ||      t%        |||t$        j&                  j4                        t%        ||dt$        j&                  j4                        g       t        |      D cg c](  }t%        |||t$        j&                  j4                        * }}|j3                  t%        ||dt$        j&                  j4                               |D ]+  }| jC                  |tE        jT                  ||      |       - |D ]+  }| jC                  |tE        jV                  ||      |       - |r)| jC                  |tE        jX                  ||      |       | j                  jZ                  }||f| j\                  v s|||f   j                         D ]  \  }}| j                  j                  |   }|j                         D ]h  \  } }!| jC                  |j^                  tE        j`                  |jH                  | |!      t%        ||dt$        j&                  j4                        g       j   yc c}w c c}w )ar  
        Find all new models (both managed and unmanaged) and make create
        operations for them as well as separate operations to create any
        foreign key or M2M relationships (these are optimized later, if
        possible).

        Defer any model options that refer to collections of fields that might
        be deferred (e.g. unique_together).
        T)rZ   reverseNr   indexesconstraintsunique_togetherr   r   r   r   rf   rd   rx   r   managers)r   r   rk   r)   rf   rg   r  rf   r   r)   indexr)   
constraintrf   r  )1rr   rt   ru   rw   r   r`   r  r6   r	   rd   rP   ra   r:   primary_keyparent_linkr   rx   rb   r   r&   r   r   rL   r   r   rc   r   r5   ry   rq   
differenceintersectionr   r   r
   r   rf   r  r  r   rM   r   AddIndexAddConstraintr   r  rs   r   r   )"r,   old_keysr  added_unmanaged_modelsall_added_modelsr   r)   r   related_fieldsprimary_key_relr0   rg   r  r  r  r   r   r   base_app_label	base_nameold_base_model_statenew_base_model_stateremoved_base_fieldsremoved_base_fielddrf   related_dependenciesr   r"  r  related_model_keyrelated_model_staterelated_field_namerelated_fields"                                     r%   r   z-MigrationAutodetector.generate_created_modelsz  s    &&)@)@@**X5!%!8!88!C <T%=%=tL)t/G/GQUV
 &6!Iz--..y*/DEKN"O%0%7%7%=%=%?!
E%%))// ,,.3.@.@.F.FO!&!3!3!?!?9>N:6u119dC5:z2 &@ "))--i8G%--11-@K)11556GNO$/$7$7$;$;'%!
 $z41D1I1I1P1PL $))dC(SD[04

30B-NI ''+*% /44;;	 ,0??+A+A+E+E'3,( ,0==+?+?+C+C'3,( ,0D 4 ; ;<'Z 4 ; ; *\+*<*<= , 3F.(// 3$2$-$6$7$<$<$C$C	!" 3F7 *J ##' )/9jQ ,0077 &&$)) "-!3!3!9!9!;!;AQ4~5 !;
 (//%++(11
 *  $ &&**9d;  &n&:&:&<=e#EEMM	  ##'!:t5H5M5M5T5T ""''#-!#
 "&c,&7!8 #   >0 %""66'.C
 ,%&1/44;;	 ,%z49L9Q9Q9X9X
" # , #>2	$ 3D $z41D1I1I1P1P 3	 ! $ !''#z41D1I1I1P1P
 !""''#-# "6 #  ! *
"",,#-#- "6 #  * ""22'(7 "6 #  //I:&$*=*==9Bz):%':5%~ +/--*>*>?P*Q'=K=Q=Q=S9*M**/99&11+>+C+C%7&3 !4$-$.$($7$<$<$C$C	!"* +  >T	:m &6^z$s   [8,-[=c                    | j                   | j                  z
  }t        |      D ]*  \  }}| j                  j                  ||f   }|j
                  j                  d      sJ t        ||dt        j                  j                        g}|j                  D ]b  }t        |t              sd|v s|j                  dd      \  }}|j                  t        ||dt        j                  j                               d | j!                  |t#        j$                  |j&                  g |j
                  |j                  |j(                        |       - y)z
        Make CreateModel statements for proxy models. Use the same statements
        as that way there's less code duplication, but for proxy models it's
        safe to skip all the pointless field stuff and chuck out an operation.
        rl   Nr   r   r  r  )rv   rs   r`   r6   r	   rx   ry   r   r&   r   r   rL   r   r   rc   r   r   r
   r   rf   r  )	r,   addedr   r)   r   r   r   r/  r0  s	            r%   r   z.MigrationAutodetector.generate_created_proxiesW  s>    ##d&9&99%+E]!Iz--..y*/DEK&&**7333 $z41D1I1I1P1PL $))dC(SD[04

30B-NI ''+*% /44;;	 * &&$))'//%++(11 *  - &3r$   c                     | j                   | j                  z  }| j                  |z
  }| j                  |z
  }t	        t        |      t        |            }|D ]  \  }}| j                  j                  ||f   }i }|j                  j                         D ]J  \  }	}
|
j                  s|
j                  j                  r|
||	<   t        |
j                  dd      sF|
||	<   L |j                  j                  dd      }|r'| j                  |t!        j"                  |d             t        |      D ])  }| j                  |t!        j$                  ||             + g }| j                  j&                  }|||f   j                         D ]  \  \  }}}|j                         D ]|  \  }	}
|j)                  t+        |||	t*        j,                  j.                               |
j0                  rH|j)                  t+        |||	t*        j,                  j2                               ~  t        |      D ]7  }|j)                  t+        |||t*        j,                  j.                               9 | j4                  j7                  ||j8                  f      }|r4|j)                  t+        g |t*        j,                  j.                          | j                  |t!        j:                  |j<                        t?        tA        |                    y)a  
        Find all deleted models (managed and unmanaged) and make delete
        operations for them as well as separate operations to delete any
        foreign key or M2M relationships (these are optimized later, if
        possible).

        Also bring forward removal of any model options that refer to
        collections of fields - the inverse of generate_created_models().
        r   Nr  r#  r)   rf   rf   r  )!ru   rw   rr   rt   r   r`   r5   r	   rd   rP   ra   r:   r   rx   rb   r   r
   r   r   r  rc   r   r&   r   many_to_manyr    r   ry   r   r   rf   rM   rq   )r,   new_keysdeleted_modelsdeleted_unmanaged_modelsall_deleted_modelsr   r)   r   r-  r0   rg   r  rf   r   r  related_object_app_labelobject_namerelation_related_fieldsthrough_users                      r%   r   z-MigrationAutodetector.generate_deleted_models  s    &&)@)@@,,x7#'#:#:X#E ">"F+C$D
 &8!Iz//00J1FGKN%0%7%7%=%=%?!
E%%))//5:z2u119dC5:z2 &@ *11556GNO""22'(, ~.""**#-! / L11I +4Iz4I*J*P*P*R' (&)@)F)F)H%J ''+4'&/44;;	 !--$++/ 8 + * 3 8 8 > >	 *I +S( ~.##'!:t5H5M5M5T5T /  --119k>T>T2UVL##'WW7J7O7O7V7VW &&$)) "#l"34  O &8r$   c                 ,   | j                   | j                  z
  }t        |      D ]m  \  }}| j                  j                  ||f   }|j
                  j                  d      sJ | j                  |t        j                  |j                               o y)z*Make DeleteModel options for proxy models.rl   r?  N)rs   rv   r`   r5   r	   rx   ry   r   r
   r   rf   )r,   deletedr   r)   r   s        r%   r   z.MigrationAutodetector.generate_deleted_proxies  s    %%(;(;;%+G_!Iz//00J1FGK&&**7333&&$)) &5r$   c                 h   g | _         | j                  j                         }t        | j                  |z
        D ]  \  }}}| j
                  j                  ||f|      }| j                  j                  ||f   }| j                  j                  ||f   }|j                  |      }| j                  |      }	t        || j                  z
        D ]\  \  }
}}|
|k(  s||k(  s|j                  |      }| j                  |      }|j                  rH|j                  j                  r2d|d   v r+|d   d   }|| j                  v r| j                  |   |d   d<   |j                  |       |j!                         d   }||	k(  s#|dd |	dd k(  st#        |d   |      |	d   k(  s| j$                  j'                  ||||      s| j                   j)                  |
||j*                  |||||f       |j-                  |
||f       |j/                  |||f       || j0                  |||f<      y)zWork out renamed fields.r_   r   r   r   )	db_columnN)renamed_operationsr   copyr`   r   r   ry   r5   r	   r6   	get_fieldrG   ra   r:   r  set_attributes_from_nameget_attname_columnrO   r7   
ask_renamerc   rL  r  rz   rp   )r,   r   r   r)   r0   r   r   new_model_staterg   	field_decr  r  rem_field_name	old_fieldold_field_dec
old_rel_toold_db_columns                    r%   r   z+MigrationAutodetector.create_renamed_fields  sm   "$,,11317.02
-Iz: "0044J'N #oo44Y5NOO"mm229j3HIO#--j9E--e4IAG!4!44B=~~ !I-.J2N / 9 9. II$($9$9)$DM**!..44 M!$44%21%5d%;
%)@)@@595L5LZ5XM!,T266~F$-$@$@$B1$EM$	1 &a*i!n< q!1]K$Q<(  ??55&
E !33::$1$2$-$7$7$2$-$.$)$.	!" +11!. O +..	:z/RS . !//	:z0QR "[B2
r$   c           	         | j                   D ]  \  }}}}}}}}||j                  k7  r?|j                         }	||	_        | j	                  |t        j                  |||	             | j	                  |t        j                  |||             | j                  j                  |||f       | j                  j                  |||f        y)z Generate RenameField operations.r  )r)   r  r  N)rM  rL  clonerf   r   r
   r   RenameFieldr   r  rz   )
r,   r  r  rem_db_columnrU  r   r)   rg   r0   altered_fields
             r%   r   z-MigrationAutodetector.generate_renamed_fields+  s     $$	

 / %%3"""))#-++ &&)+' &&~~'VW##Y
J$GH1 %r$   c                     t        | j                  | j                  z
        D ]  \  }}}| j                  |||        y)zMake AddField operations.N)r`   r   r   _generate_added_fieldr   s       r%   r   z+MigrationAutodetector.generate_added_fieldsP  s@    17$"5"552
-Iz: &&y*jI2
r$   c           	         | j                   j                  ||f   j                  |      }t        |||t        j                  j
                        g}|j                  rC|j                  j                  r-|j                  | j                  |||| j                                |j                  r |j                  | j                  |             t        j                  t        j                  t        j                  f}|j                  xst |j!                         xsb |j"                  t        j$                  uxsD |j&                  xs6 |j(                  xr |j*                  xs t-        ||      xr |j.                  }|sk|j1                         }t-        ||      r.|j2                  r"| j4                  j7                  ||      |_        n!| j4                  j;                  ||      |_        |j<                  rM|j8                  t        j$                  ur1t?        |j8                        r| j4                  jA                  ||       | jC                  |tE        jF                  ||||      |       y )Nr)   rf   rg   preserve_defaultr  )$r6   r	   rO  r   r&   r   ra   r:   r
  r  	generated%_get_dependencies_for_generated_field	DateFieldDateTimeField	TimeFieldnullhas_default
db_defaultNOT_PROVIDEDr@  blankempty_strings_allowedrL   auto_nowr[  auto_now_addr7   ask_auto_now_add_additiondefaultask_not_null_additionuniquecallable$ask_unique_callable_default_additionr   r
   r   )r,   r   r)   r0   rg   r   time_fieldsrc  s           r%   r`  z+MigrationAutodetector._generate_added_fieldW  s   $$Y
%:;EEjQ  :z3F3K3K3R3R
 %"4"4":":66MM	 ?? J J5 QR '')=)=v?O?OPJJ C  "Cv':'::C !!C ; ; ;	C
 5+.A5>> 	  KKME%-%2D2D $ I I
! !% E E
! LLV%8%88'OO@@ZX%!1	 & 	 		
r$   c                     t        | j                  | j                  z
        D ]  \  }}}| j                  |||        y)zMake RemoveField operations.N)r`   r   r   _generate_removed_fieldr   s       r%   r   z-MigrationAutodetector.generate_removed_fields  s@    17$"5"552
-Iz: ((J
K2
r$   c                     | j                  |t        j                  ||      t        |||t        j                  j
                        t        |||t        j                  j                        g       y )Nr>  r  )r   r
   r   r   r&   r!   r"   r   s       r%   ry  z-MigrationAutodetector._generate_removed_field  su    ""% $',,==	 $',,??	 	 	
r$   c           
      	   t        | j                  | j                  z        D ]U  \  }}}| j                  j	                  ||f|      }| j
                  j	                  |||f|      }| j                  j                  ||f   j                  |      }| j                  j                  ||f   j                  |      }g }t        |d      rt        |j                  dd      rt        |j                  j                  ||      }	|	| j                  v r%|j                  j                  |j                  _        t        |j                  dd      }
|
r^|	|
fz   }|| j
                  v rJ|j                  j                  |j                  _        |j                  j                  |j                  _        t        |dd      }|r||f}t!        |D cg c]"  }| j
                  j	                  ||fz   |      $ c}      |_        t!        |j$                  D cg c]"  }| j
                  j	                  |	|fz   |      $ c}      |_        t        |dd      x}r*t!        |      |_        t!        |j$                        |_        |j'                  | j)                  |||| j                               t        |d      rkt        |j                  dd      rTt        |j                  j*                  ||      }	|	| j                  v r%|j                  j*                  |j                  _        | j-                  |      }| j-                  |      }||k7  s&||k(  s-|j.                  xr |j.                  }|j.                   xr |j.                   }|s|rd}|j0                  r|j0                  s|j3                         sp|j4                  t        j6                  u rT|j.                  sH|j9                         }| j:                  j=                  ||      }|t        j6                  ur||_        d}n|}| jA                  |tC        jD                  ||||	      |
       0| jG                  |||       | jI                  |||       X yc c}w c c}w )zp
        Make AlterField operations, or possibly RemovedField/AddField if alter
        isn't possible.
        ra   r:   Nr0   from_fieldsr   TFrb  r  )%r`   r   r   r   ry   rp   r5   r	   rO  r6   rW   r   ra   r   r:   r0   rN   r|  	to_fieldsr
  r  r   rG   r@  ri  rj  rk  rl  r[  r7   ask_not_null_alterationrr  r   r
   r   ry  r`  )r,   r   r)   r0   r   old_field_namerV  	new_fieldr   
rename_keyremote_field_nameto_field_rename_keyr|  from_rename_key
from_fieldto_fieldold_from_fieldsrW  new_field_decboth_m2mneither_m2mrc  rg   new_defaults                           r%   r   z-MigrationAutodetector.generate_altered_fields  sx   
 28$"5"552
-Iz: "0044J'N "0044J
3ZN ..y./HISSI ,,Y
-BCMMI L y.1g&&7 .**00)Z
 !4!443<3I3I3O3OI**0$+I,B,BLRV$W!$*48I7K*K'*d.A.AA 8A7M7M7S7S	..4%22== "..9 &iE'0*&=O,1
 /:	 /:
 !//33 /:- ? /:	-I) +0 -6,?,?,? !//33J(4LhW,?+I' +2)]D*QQQ05o0F	-.3I4G4G.H	+##::!"!	 y.1g&&	47 .**22Iz
 !4!445>5K5K5S5SI**2 11)<M 11)<M -.J2N$11Li6L6L"+"8"88WAWAW=W{'+$! ) ) 5 5 7%00F4G4GG ) 6 6 ) 1&*oo&M&M&
' 'f.A.AA,7EM/4, )&&!"--'1!+"'-=	 &2 ' 	 00J
S..y*jQi2
Xs   
'Q=
'R
c                    t         j                  j                  }t        t              | _        t        | j                        D ]  \  }}| j                  j                  ||f|      }| j                  j                  ||f   }| j                  j                  ||f   }|j                  |   }|j                  |   }|D 	cg c]	  }	|	|vs|	 }
}	|D 	cg c]	  }	|	|vs|	 }}	g }g }g }|
D ]  }|j                         }|d   j                  d      }|D ]h  }|j                         }|d   j                  d      }||k(  s-||k7  s3|j!                  ||d f       |j!                  |       |j!                  |       j  | j#                  t         j$                  j                        D ]  \  }}}}}||k7  s||k7  r|j'                  |      }|D ]  }g }|
D ]T  }|j                         \  }}}|r|j(                  t	        |      k(  s3t+        |      ddhk(  sD|j!                  |       V t-        |      dk(  sm|d   } |j!                  |        |j!                  d | j.                  |f       | j
                  ||f   j!                  |         |
D 	cg c]	  }	|	|vs|	 }
}	|D 	cg c]	  }	|	|vs|	 }}	| j0                  j3                  ||f|
||di        y c c}	w c c}	w c c}	w c c}	w )Nr   rf   rd   r   r   )added_indexesremoved_indexesrenamed_indexes)r
   r(  option_namer   rM   renamed_index_together_valuesr`   r   r   ry   r5   r	   r6   rx   rK   rb   rc   $_get_altered_foo_together_operationsr   r&  rd   rq   r   rf   rn   r   )!r,   r  r   r)   r   r   rS  old_indexesnew_indexesidxr  r  r  remove_from_addedremove_from_removed	new_indexnew_index_decnew_index_name	old_indexold_index_decold_index_name	old_value	new_valueindex_together_app_labelindex_together_model_namer   removed_valuesremoved_index_togetherrenamed_index_together_indexes_rT   r]   renamed_indexs!                                    r%   r   z,MigrationAutodetector.create_altered_indexes-  sX    ))55-8->*%+D,@,@%A!Iz!0044J'N #oo44Y5NOO"mm229j3HIO)11+>K)11+>K,7RKS3k;QSKMR.9TksS=SskOT O ""$*	 ) 5 5 7!.q!1!5!5f!=!0I$-$9$9$;M%21%5%9%9&%AN &6*n<'..PT/UV)00;+229= "1 +* ::--99()
 !99!%>>!*!5!5i!@.<*572%2	*3*?*?*A4 !% ) 0 0D9O4P P #F/A A:AA)L &3 9:a?(Fq(I)00?'..!=#5#57MN ::46OO &!78) /=B  -,;L0L}    /.#=P2P     ''
+)6+:+:.W &B STts0   	K'K'	K,K,	K1&K10	K6:K6c           	          | j                   j                         D ]M  \  \  }}}| j                  ||      }|d   D ]+  }| j                  |t	        j
                  ||      |       - O y )Nr  r  r  )rn   rP   _get_dependencies_for_modelr   r
   r(  )r,   r   r)   alt_indexesr   r   s         r%   r   z,MigrationAutodetector.generate_added_indexes  sv    484H4H4N4N4P0#Y
[;;IzRL$_5""''#-# ". #  6 5Qr$   c           	          | j                   j                         D ]C  \  \  }}}|d   D ]3  }| j                  |t        j                  ||j
                               5 E y )Nr  r>  )rn   rP   r   r
   RemoveIndexrf   )r,   r   r)   r  r   s        r%   r   z.MigrationAutodetector.generate_removed_indexes  s_    484H4H4N4N4P0#Y
[$%67""**#-"ZZ 8 5Qr$   c                     | j                   j                         D ]?  \  \  }}}|d   D ]/  \  }}}| j                  |t        j                  ||||             1 A y )Nr  )r)   r  r  
old_fields)rn   rP   r   r
   RenameIndex)r,   r   r)   r  r  r  r  s          r%   r   z.MigrationAutodetector.generate_renamed_indexes  sl    484H4H4N4N4P0#Y
[>I!?:
 ""**#-!/!/#-	? 5Qr$   c                    t         j                  j                  }t        | j                        D ]  \  }}| j
                  j                  ||f|      }| j                  j                  ||f   }| j                  j                  ||f   }|j                  |   }|j                  |   }|D 	cg c]	  }	|	|vs|	 }
}	|D 	cg c]	  }	|	|vs|	 }}	| j                  j                  ||f|
|di        y c c}	w c c}	w )N)added_constraintsremoved_constraints)r
   r)  r  r`   r   r   ry   r5   r	   r6   rx   ro   r   )r,   r  r   r)   r   r   rS  old_constraintsnew_constraintscadd_constraintsrem_constraintss               r%   r   z0MigrationAutodetector.create_altered_constraints  s    ..::%+D,@,@%A!Iz!0044J'N #oo44Y5NOO"mm229j3HIO-55kBO-55kBO*9V/QQo=Uq/OV*9V/QQo=Uq/OV$$++
+-</>. &B WVs   ,	C56C5 	C:
C:c           	          | j                   j                         D ]M  \  \  }}}| j                  ||      }|d   D ]+  }| j                  |t	        j
                  ||      |       - O y )Nr  r!  r  )ro   rP   r  r   r
   r)  )r,   r   r)   alt_constraintsr   r"  s         r%   r   z0MigrationAutodetector.generate_added_constraints  s     #66<<> 
;;IzRL-.AB
"",,#-#- ". #  C ?r$   c           	          | j                   j                         D ]C  \  \  }}}|d   D ]3  }| j                  |t        j                  ||j
                               5 E y )Nr  r>  )ro   rP   r   r
   RemoveConstraintrf   )r,   r   r)   r  r"  s        r%   r   z2MigrationAutodetector.generate_removed_constraints  sh     #66<<> 
-.CD
""//#-'__ E ?r$   c                    d }t        j                  d      rj                  j                  }nW|j                  | |f   }|j	                         D ]3  \  \  }}}t        fd|j                         D              s,| d| } n t        dd       }	|	d}
|	}nt        || |      \  }
}t        |
|d t        j                  j                        g}t        j                  dd       rYt        j                  j                  | |      \  }}|j                  t        ||d t        j                  j                               |S )Nr:   c              3   <   K   | ]  }|j                   k(    y wr(   )ra   )rH   r:  rg   s     r%   rJ   zJMigrationAutodetector._get_dependencies_for_foreign_key.<locals>.<genexpr>  s$      )8 ]777)8s   r   swappable_settingr   r   )rW   ra   r:   r  rP   r   r   r   r   r   r&   r   r   rc   )r   r)   rg   project_stateremote_field_modelr  remote_app_labelremote_model_namerd   r  dep_app_labeldep_object_namer   through_app_labelthrough_object_names     `            r%   r  z7MigrationAutodetector._get_dependencies_for_foreign_key  sf   !5%%w/!&!3!3!9!9%//	:0EFIAJAR=5!#4v )/  -=+=Q?P>Q)R& BS $E+>E()M/O-=".*M?  6I6N6N6U6U

 5%%y$75E""**622
 #%'',,33	 r$   c           	         g }t        j                  |j                        j                  }t	        | j
                  | j                  z
        }|D ]  \  }}}| j                  j                   ||f   j                  |      }|j                  r|j                  j                  s|j                  |v sb|j                  t        |||j                  t        j                  j                                |S r(   )r	   Q
expressionreferenced_base_fieldsr`   r   r   r6   rO  ra   r:   rf   rc   r   r&   r   )	r,   rg   r   r  newly_added_fieldsr   r)   added_field_nameadded_fields	            r%   re  z;MigrationAutodetector._get_dependencies_for_generated_field  s    !'%*:*:!;!R!R#D$7$7$:M:M$MN7I3Iz#3--..y*/DEOO K (([-E-E-K-K!!%;;##'!"#((+0077	 8J r$   c           	          g }| j                   j                  ||f   }|j                  j                         D ]<  }|j                  s|j                  | j                  |||| j                                > |S )z3Return foreign key dependencies of the given model.)r6   r	   rd   r   r	  r
  r  )r,   r   r)   r   r   rg   s         r%   r  z1MigrationAutodetector._get_dependencies_for_model%  sv    mm**9j+@A ''..0E  ##::!"	 1 r$   c              #      K   t         j                        D ]X  \   j                  j                  f      } j                  j
                  |f   } j                  j
                  f   }|j                  j                  |      }|r$|D ch c]  }t         fd|D               c}n	t               }|j                  j                  |      }|rt        |      n	t               }||k7  sg }|D ]k  }	|	D ]d  }
|j                  |
      }|j                  s!|j                  j                  s8|j                   j                  | j                               f m |||f [ y c c}w w)Nc              3   \   K   | ]#  }j                   j                  |f|       % y wr(   )rp   ry   )rH   nr   r)   r,   s     r%   rJ   zMMigrationAutodetector._get_altered_foo_together_operations.<locals>.<genexpr>A  s3      !'A ++//J0JAN!'s   ),)r`   r   r   ry   r5   r	   r6   rx   rN   rq   rO  ra   r:   r
  r  )r,   r  r   r   rS  r  rt  r  r   foo_togethersr0   rg   r   r)   s   `           @@r%   r  z:MigrationAutodetector._get_altered_foo_together_operations5  s    %+D,@,@%A!Iz!0044J'N #oo44Y5NOO"mm229j3HIO (//33K@I  #,
 #,	  !'  #, U  (//33K@I*3III%!%.M&3
 / 9 9* E --%2D2D2J2J(// $ F F$-$.$)$(MM	!" '4 &/   M &Bs&   BE=E84AE=9)E=#E=:AE=c           
      @   | j                  |j                        D ]{  \  }}}}}|t        j                  k(  r"|D ch c]  }|| j                  ||f   vr| }}|j                  |      }|s|sT| j                  | |dd|i|j                  |i|       } y c c}w Nrf   r  r#   )r  r  r
   r   r  r'  r   )	r,   r   r  r  r   r)   r   rI   removal_values	            r%   &_generate_removed_altered_foo_togetherz<MigrationAutodetector._generate_removed_altered_foo_togetherd  s     66y7L7LM
J999 "+!*==i>STU !*   &229=M	"" ',5,A,A=+Q ". #  Ns   Bc                 B    | j                  t        j                         y r(   )r  r
   r   r+   s    r%   r   z>MigrationAutodetector.generate_removed_altered_unique_together}  s    33J4R4RSr$   c           
          | j                  |j                        D ]G  \  }}}}}|j                  |      }||k7  s | j                  | |dd|i|j                  |i|       I y r  )r  r  r'  r   )r,   r   r  r  r   r)   r   r  s           r%   _generate_altered_foo_togetherz4MigrationAutodetector._generate_altered_foo_together  s~     66y7L7LM
%229=MM)""T:T)2G2G1ST!- #  Nr$   c                 B    | j                  t        j                         y r(   )r  r
   r   r+   s    r%   r   z6MigrationAutodetector.generate_altered_unique_together  s    ++J,J,JKr$   c                    | j                   j                  | j                  | j                        }t	        |      D ]  \  }}| j
                  j                  ||f|      }| j                  j                  ||f   }| j                  j                  ||f   }|j                  j                  d      }|j                  j                  d      }||k7  s| j                  |t        j                  ||              y )Ndb_table)rf   table)r   unionr   r   r`   r   ry   r5   r	   r6   rx   r   r
   AlterModelTable)	r,   models_to_checkr   r)   r   r   rS  old_db_table_namenew_db_table_names	            r%   r   z/MigrationAutodetector.generate_altered_db_table  s    ..44  $":":
 &,O%<!Iz!0044J'N #oo44Y5NOO"mm229j3HIO / 7 7 ; ;J G / 7 7 ; ;J G $55""..'/ &=r$   c                    | j                   j                  | j                  | j                        }t	        |      D ]  \  }}| j
                  j                  ||f|      }| j                  j                  ||f   }| j                  j                  ||f   }|j                  j                  d      }|j                  j                  d      }||k7  s| j                  |t        j                  ||              y )Ndb_table_comment)rf   table_comment)r   r  r   r   r`   r   ry   r5   r	   r6   rx   r   r
   AlterModelTableComment)	r,   r  r   r)   r   r   rS  old_db_table_commentnew_db_table_comments	            r%   r   z7MigrationAutodetector.generate_altered_db_table_comment  s    ..44  $":":
 &,O%<!Iz!0044J'N #oo44Y5NOO"mm229j3HIO#2#:#:#>#>?Q#R #2#:#:#>#>?Q#R #';;""55'&: &=r$   c                    | j                   j                  | j                  | j                  | j                  | j
                  z  | j                  | j                  z        }t        |      D ]  \  }}| j                  j                  ||f|      }| j                  j                  ||f   }| j                  j                  ||f   }|j                  j                         D ci c]  \  }}|t         j"                  v r|| }	}}|j                  j                         D ci c]  \  }}|t         j"                  v r|| }
}}|	|
k7  s| j%                  |t'        j                   ||
              yc c}}w c c}}w )z
        Work out if any non-schema-affecting options have changed and make an
        operation to represent them in state changes (in case Python code in
        migrations needs them).
        )rf   rx   N)r   r  r   r   rt   ru   rr   rw   r`   r   ry   r5   r	   r6   rx   rP   r   ALTER_OPTION_KEYSr   r
   )r,   r  r   r)   r   r   rS  rZ   rI   old_optionsnew_optionss              r%   r   z.MigrationAutodetector.generate_altered_options  s    ..44  $$##d&9&99$"9"99
 &,O%<!Iz!0044J'N #oo44Y5NOO"mm229j3HIO #2"9"9"?"?"A"AJC+=== U
"A   #2"9"9"?"?"A"AJC+=== U
"A  
 k)""00' +# &=
s   $E6#E<c           
         t        | j                        D ]3  \  }}| j                  j                  ||f|      }| j                  j
                  ||f   }| j                  j
                  ||f   }|j                  j                  d      |j                  j                  d      k7  sg }|j                  j                  d      rB|j                  t        |||j                  d   t        j                  j                               | j                  |t        j                  ||j                  j                  d            |       6 y )Nr   r  r  )r`   r   r   ry   r5   r	   r6   rx   rc   r   r&   r   r   r
   r   )r,   r   r)   r   r   rS  r   s          r%   r   z<MigrationAutodetector.generate_altered_order_with_respect_to  s>   %+D,@,@%A!Iz!0044J'N #oo44Y5NOO"mm229j3HIO&&**' ((,,-DEF
  ""**../FG ''+%&+334KL/44;;	 ""66'.=.E.E.I.I3/ ". # 	- &Br$   c                 |   t        | j                        D ]  \  }}| j                  j                  ||f|      }| j                  j
                  ||f   }| j                  j
                  ||f   }|j                  |j                  k7  st| j                  |t        j                  ||j                                y )N)rf   r  )r`   r   r   ry   r5   r	   r6   r  r   r
   AlterModelManagers)r,   r   r)   r   r   rS  s         r%   r   z/MigrationAutodetector.generate_altered_managers  s    %+D,@,@%A!Iz!0044J'N #oo44Y5NOO"mm229j3HIO''?+C+CC""11'!0!9!9 &Br$   c           	      j   |j                         }i }t        |j                               D ]3  \  }}|s
d}|D ]  }	|	d   |k(  s|	} n |9| j                  j	                  |      s|D ]  }
|df|||
j
                  f<    ||= Z|d}n| j                  |d         xs ddz   }t        |      D ]  \  }}
|dk(  r|r|
j                  j                  |       d|z  g}|r|j                  |       n;|dk(  r|s|j                  d       n"|j                  |
j                         dd        dj                  |      }||f|||
j
                  f<   |dz  }||
_         6 |j                         D ]8  }|D ]1  }
|
j                  D cg c]  }|j                  ||       c}|
_        3 : |S c c}w )	z
        Take a result from changes() and a MigrationGraph, and fix the names
        and dependencies of the changes so they extend the graph from the leaf
        nodes for each app.
        Nr   r   r   z%04ir   d   r  )r   rM   rP   r7   ask_initialrf   parse_number	enumerater   rc   suggest_namejoinr   ry   )r,   rD   r@   rC   leavesname_mapr   r   app_leafleafr   next_numberinew_name_partsr  r5  s                   r%   r>   z'MigrationAutodetector.arrange_for_graph  s    !!#%)'--/%:!IzH7i'#H 
 (C(CI(N!+I=F<THi89 ",I&#00!=BaG )* 596h**11(;"(;"6!7!")).9!VH")))4")))*@*@*B4C*HI88N39BH8M)Y^^45q !)	 !6- &;J "..*J'	090F0F*0F1HLLA&0F*	& ( +
 *s   	F0c           	         i }|j                         D ]I  \  }}|D ]?  }|j                  D ].  \  }}|j                  |t                     j	                  |       0 A K t        |      }	d}
|
|	k7  r>t        |	      }
 |	j
                  |	D cg c]  }|j                  |d       c}  |
|	k7  r>t        |      D ]
  }||	vs||=  |S c c}w )a1  
        Take changes from arrange_for_graph() and set of app labels, and return
        a modified set of changes which trims out as many migrations that are
        not in app_labels as possible. Note that some other migrations may
        still be present as they may be required dependencies.
        Nr#   )rP   r   r   rq   rz   r   ry   rM   )r,   rD   
app_labelsapp_dependenciesr   r   r   r  rf   required_appsold_required_appss              r%   r?   z#MigrationAutodetector._trim_to_appsL  s     %,]]_!Iz'	+4+A+A'M4$//	35AEEmT ,B ( &5 J =0 #M 2 M  GTU})"&&y"5}U  =0 gI-I& '  Vs   C	c                     t        j                  d|      x}rt        |d         S t        j                  d|      }|rt        |d         S y)u   
        Given a migration name, try to extract a number from the beginning of
        it. For a squashed migration such as '0001_squashed_0004…', return the
        second number. If no number is found, return None.
        z.*_squashed_(\d+)r   z^\d+r   N)researchintmatch)clsrf   squashed_matchr  s       r%   r  z"MigrationAutodetector.parse_numberg  sO      YY';TBB>B~a())$'uQx= r$   r(   )NNN)NN)NF)7r   r   r   __doc__r;   rD   rG   ri   r=   r~   r   staticmethodr   r   r   r   r   r   r  r}   r   r   r   r   r   r   r   r`  r   ry  r   r   r   r   r   r   r   r   r  re  r  r  r  r   r  r   r   r   r   r   r   r>   r?   classmethodr  r#   r$   r%   r3   r3   *   sM   
G
$LgR
.( 
 
(v"pK$$RKhR.B"H[z(T]~<"|#IJJ8
tL
4yRvWr	.  + +Z* -^2T L*,&P D 2h6  r$   r3   )!rQ   r  collectionsr   r   enumr   graphlibr   	itertoolsr   django.confr   	django.dbr	   django.db.migrationsr
   django.db.migrations.migrationr   &django.db.migrations.operations.modelsr   django.db.migrations.optimizerr   django.db.migrations.questionerr   django.db.migrations.utilsr   r   r   django.utils.functionalr   r   r3   r#   r$   r%   <module>r     s]     	 /  &     + 4 D = ? 
 4'$&LM'&I Ir$   