
    hA                         S SK r S SKrS SKJrJr  S SKJr  S SKJr  S SK	J
r
  S SKJr  SSKJrJrJrJr  S	r " S
 S5      rg)    N)import_modulereload)apps)settings)MigrationGraph)MigrationRecorder   )AmbiguityErrorBadMigrationErrorInconsistentMigrationHistoryNodeNotFoundError
migrationsc                   ~    \ rS rSrSr   SS jr\S 5       rS rS r	S r
S rS	 rS
 rS rS rS rSS jrS rSrg)MigrationLoader   a$  
Load migration files from disk and their status from the database.

Migration files are expected to live in the "migrations" directory of
an app. Their names are entirely unimportant from a code perspective,
but will probably follow the 1234_name.py convention.

On initialization, this class will scan those directories, and open and
read the Python files, looking for a class called Migration, which should
inherit from django.db.migrations.Migration. See
django.db.migrations.migration for what that looks like.

Some migrations will be marked as "replacing" another set of migrations.
These are loaded into a separate set of migrations away from the main ones.
If all the migrations they replace are either unapplied or missing from
disk, then they are injected into the main set, replacing the named migrations.
Any dependency pointers to the replaced migrations are re-pointed to the
new migration.

This does mean that this class MUST also talk to the database as well as
to disk, but this is probably fine. We're already not just operating
in memory.
c                 t    Xl         S U l        S U l        X0l        X@l        U(       a  U R                  5         g g N)
connectiondisk_migrationsapplied_migrationsignore_no_migrationsreplace_migrationsbuild_graph)selfr   loadr   r   s        M/var/www/html/env/lib/python3.13/site-packages/django/db/migrations/loader.py__init__MigrationLoader.__init__-   s9     %#"&$8!"4     c                     U[         R                  ;   a  [         R                  U   S4$ [        R                  " U5      R                  nU< S[
        < 3S4$ )z
Return the path to the migrations module for the specified app_label
and a boolean indicating if the module is specified in
settings.MIGRATION_MODULE.
T.F)r   MIGRATION_MODULESr   get_app_confignameMIGRATIONS_MODULE_NAME)cls	app_labelapp_package_names      r   migrations_module!MigrationLoader.migrations_module<   sP     222--i8$>>#229=BB.0FGNNr   c           	         0 U l         [        5       U l        [        5       U l        [        R
                  " 5        GH  nU R                  UR                  5      u  p#Uc'  U R                  R                  UR                  5        MK  U[        R                  ;   n [        U5      n[        US5      (       d'  U R                  R                  UR                  5        M  [        USS5      cF  [        UR                  [         5      (       d'  U R                  R                  UR                  5        M  U(       a  [#        U5        U R                  R                  UR                  5        [.        R0                  " UR                  5       VVV	s1 s H  u  pxn	U	(       a  M  US   S;  d  M  UiM     n
nnn	U
 H|  nU< SU< 3n [        U5      n[        US	5      (       d  [7        S
U< SUR                  < S35      eUR9                  UUR                  5      U R                   UR                  U4'   M~     GM     g! [$         at  nU(       a  U R&                  (       d*  U(       dO  [(        UR*                  R-                  S5      ;   a,  U R                  R                  UR                  5         SnAGMx  e SnAff = fs  sn	nnf ! [2         a$  nS[5        U5      ;   a  [3        SU-  5      Uee SnAff = f)z6Load the migrations from all INSTALLED_APPS from disk.N__path____file__r!   r   z_~zbad magic numberz9Couldn't import %r as it appears to be a stale .pyc file.	Migrationz
Migration z in app z has no Migration class)r   setunmigrated_appsmigrated_appsr   get_app_configsr)   labeladdsysmodulesr   hasattrgetattr
isinstancer,   listr   ModuleNotFoundErrorr   r%   r$   splitpkgutiliter_modulesImportErrorstrr   r.   )r   
app_configmodule_nameexplicit
was_loadedmodulee_r$   is_pkgmigration_namesmigration_namemigration_pathmigration_modules                 r   	load_diskMigrationLoader.load_diskI   s   !"u U..0J$($:$::;K;K$L!K"$$(()9)9:$3J#&{3 vz22((,,Z-=-=> 6:t4<ZOOTF F ((,,Z-=-=>6N"":#3#34 (/';';FOO'L'LOAV "&q'"5 'L   #2,7!H	'4^'D$ /==+):+;+;= 
 %..&"(( $$Z%5%5~%EF# #2O 1 ' !:!: %;qvv||C?P%P((,,Z-=-=>0 # )SV3))+9:  !!
 sI   H;J<
J<
)J<
K;
J9A'J43J44J9
K1K,,K1c                 6    U R                   R                  X4   $ )z6Return the named migration or raise NodeNotFoundError.graphnodes)r   r'   name_prefixs      r   get_migrationMigrationLoader.get_migration   s    zz	 677r   c                 .   / nU R                    H6  u  pEXA:X  d  M  UR                  U5      (       d  M$  UR                  XE45        M8     [        U5      S:  a  [	        SU< SU< S35      eU(       d  [        SU SU S35      eU R                   US      $ )zJ
Return the migration(s) which match the given app label and name_prefix.
r	   z&There is more than one migration for 'z' with the prefix ''zThere is no migration for 'r   )r   
startswithappendlenr
   KeyError)r   r'   rS   resultsmigration_app_labelrJ   s         r   get_migration_by_prefix'MigrationLoader.get_migration_by_prefix   s    
 373G3G/"/N4M4M5 5  3DE	 4H
 w<! k+  -i[ 9=# 
 ''
33r   c                    US   S:w  a	  US   S:w  d  XR                   ;   a  U$ US   U:X  a  g US   U R                  ;   a  g US   U R                  ;   aL   US   S:X  a!  U R                   R                  US   5      S   $ U R                   R	                  US   5      S   $ [        SUS   -  5      e! [
         a%    U R                  (       a   g [        SUS   -  5      ef = f)Nr	   	__first__
__latest__r   z(Dependency on app with no migrations: %szDependency on unknown app: %s)rQ   r0   r1   
root_nodes
leaf_nodes
IndexErrorr   
ValueError)r   keycurrent_apps      r   	check_keyMigrationLoader.check_key   s    Fk!c!f&<

ARJ
 q6[ q6T))) q6T'''q6[(::00Q8;;::00Q8;; 83q6ABB  ,,$BSVK 	s   )B2   B2 2C!C!c                     UR                    H7  nUS   US   :X  d  M  US   S:w  d  M  U R                  R                  X!USS9  M9     g)zm
Internal dependencies need to be added first to ensure `__first__`
dependencies find the correct root node.
r   r	   ra   Tskip_validationN)dependenciesrQ   add_dependency)r   rg   	migrationparents       r   add_internal_dependencies)MigrationLoader.add_internal_dependencies   sI    
  ,,FayCF"vayK'?

)))&RV)W -r   c                 <   UR                    HE  nUS   US   :X  a  M  U R                  X1S   5      nUc  M*  U R                  R                  X!USS9  MG     UR                   H7  nU R                  XAS   5      nUc  M  U R                  R                  X$USS9  M9     g )Nr   Trl   )rn   ri   rQ   ro   
run_before)r   rg   rp   rq   childs        r   add_external_dependencies)MigrationLoader.add_external_dependencies   s    ,,F1v"^^FF3F!

)))&RV)W - ))ENN5a&1E 

)))CQU)V *r   c           	      0  ^  T R                  5         T R                  c  0 T l        O*[        T R                  5      nUR                  5       T l        [	        5       T l        0 T l        T R                  R                  5        HB  u  p#T R
                  R                  X#5        UR                  (       d  M3  UT R                  U'   MD     T R                  R                  5        H  u  p#T R                  X#5        M     T R                  R                  5        H  u  p#T R                  X#5        M     T R                  (       a  T R                  R                  5        H  u  p#UR                   Vs/ s H  oDT R                  ;   PM     nn[        U5      (       a  UT R                  U'   OT R                  R                  US5        [        U5      (       d  [!        U5      (       d'  T R
                  R#                  X#R                  5        M  T R
                  R%                  X#R                  5        M      T R
                  R'                  5         T R
                  R;                  5         gs  snf ! [(         Ga  n0 nT R                  R                  5        HA  u  p#UR                   H,  nUR+                  U[-        5       5      R/                  U5        M.     MC     UR0                  U;   a  UR3                  UR0                  [-        5       5      n	[!        U 4S jU	 5       5      n
U
(       de  SR5                  S U	 5       5      n[)        SR7                  UR8                  UR0                  S   UR0                  S   U5      UR0                  5      Uee SnAff = f)z
Build a migration dependency graph using both the disk and database.
You'll need to rebuild the graph if you apply migrations. This isn't
usually a problem as generally migration stuff runs in a one-shot process.
Nc              3   T   >#    U  H  oTR                   R                  ;   v   M     g 7fr   rP   ).0	candidater   s     r   	<genexpr>.MigrationLoader.build_graph.<locals>.<genexpr>"  s!      "CMi!1!11:s   %(z, c              3   ,   #    U  H
  nS U-  v   M     g7f)z%s.%sN )r{   cs     r   r}   r~   &  s     %F:agk:s   zMigration {0} depends on nonexistent node ('{1}', '{2}'). Django tried to replace migration {1}.{2} with any of [{3}] but wasn't able to because some of the replaced migrations are already applied.r   r	   )rM   r   r   r   r   rQ   replacementsr   itemsadd_nodereplacesrr   rw   r   allpopanyremove_replaced_nodesremove_replacement_nodevalidate_consistencyr   
setdefaultr/   r4   nodegetjoinformatoriginensure_not_cyclic)r   recorderrg   rp   targetapplied_statusesexcreverse_replacementsreplaced
candidatesis_replacedtriess   `           r   r   MigrationLoader.build_graph   s    	??"&(D#(9H&.&A&A&CD# $%
"2288:NCJJ/!!!)2!!#&	 ;
 #2288:NC**3: ; #2288:NC**3: ; """&"3"3"9"9"; GPFXFX$FXFt666FX ! $
 '((3<D++C0++//T: '((5E1F1FJJ44S:L:LM
 JJ66s<N<NO) #<,	JJ++-: 	

$$&c$* ! 	 $& "&"3"3"9"9"; ) 2 2H(33HceDHHM !3 #< xx//155chhF
! "CM"  # II%F:%FFE+/ 06vJJSXXa[%0   7	s   -I)4I. .N9DNNc                   ^ [        U5      nUR                  5       mT H  nX0R                  R                  ;  a  M  U R                  R                  U   R
                   H  nUT;  d  M  X@R                  ;   a3  [        U4S jU R                  U   R                   5       5      (       a  MM  [        SR                  US   US   US   US   UR                  5      5      e   M     g)z[
Raise InconsistentMigrationHistory if any applied migrations have
unapplied dependencies.
c              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   )r{   mapplieds     r   r}   ;MigrationLoader.check_consistent_history.<locals>.<genexpr>C  s      2TQL2Ts   zHMigration {}.{} is applied before its dependency {}.{} on database '{}'.r   r	   N)r   r   rQ   rR   node_mapparentsr   r   r   r   r   alias)r   r   r   rp   rq   r   s        @r   check_consistent_history(MigrationLoader.check_consistent_history3  s    
 %Z0--/ I

 0 00**--i8@@( !2!22 262C2CF2K2T2T   %6228&%aL%aL"1I"1I&,,3	 	 A	 !r   c                 $   0 n[        5       nU R                  R                  5        HD  u  p4X1;   a  UR                  U5        UR	                  U[        5       5      R                  U5        MF     U Vs0 s H  o3[        X   5      _M     sn$ s  snf )z
Look through the loaded graph and detect any conflicts - apps
with more than one leaf migration. Return a dict of the app labels
that conflict with the migration names that conflict.
)r/   rQ   rd   r4   r   sorted)r   	seen_appsconflicting_appsr'   rJ   s        r   detect_conflicts MigrationLoader.detect_conflictsR  s     	5)-)>)>)@%I% $$Y/  CE266~F *A
 FV
EU	vi233EU
 	
 
s   3BNc                 J    U R                   R                  XU R                  S9$ )z
Return a ProjectState object representing the most recent state
that the loaded migrations represent.

See graph.make_state() for the meaning of "nodes" and "at_end".
)rR   at_end	real_apps)rQ   
make_stater0   )r   rR   r   s      r   project_stateMigrationLoader.project_stateb  s+     zz$$$2F2F % 
 	
r   c                 x   / nSnU H  u  pEU R                   R                  SUR                  S9 nUc&  U R                  UR                  UR
                  4SS9nU(       d  UR                  X6SS9nOUR                  X6SS9nSSS5        UR                  WR                  5        M     U$ ! , (       d  f       N/= f)z{
Take a migration plan and return a list of collected SQL statements
that represent the best-efforts version of that plan.
NT)collect_sqlatomicF)r   )r   )
r   schema_editorr   r   r'   r$   applyunapplyextendcollected_sql)r   plan
statementsstaterp   	backwardsr   s          r   r   MigrationLoader.collect_sqlm  s    
 
$( I.. )9)9 / = ..",,inn=e / E !%OOEdOSE%--ePT-UE m99: %)  s   AB++
B9	)	r   r   r   rQ   r   r1   r   r   r0   )TFT)NT)__name__
__module____qualname____firstlineno____doc__r   classmethodr)   rM   rT   r^   ri   rr   rw   r   r   r   r   r   __static_attributes__r   r   r   r   r      sk    6 " 
O 
OBH840C<XWS'j>
 	
r   r   )r=   r5   	importlibr   r   django.appsr   django.confr   django.db.migrations.graphr   django.db.migrations.recorderr   
exceptionsr
   r   r   r   r%   r   r   r   r   <module>r      s8     
 +    5 ;  & m mr   