
     +h                        d Z ddlZddlZddlZddlmZmZmZmZ ddl	m
Z
 ddlmZ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 dd
lmZmZ ddlmZ ddlmZ  edd          Ze e!ffdZ"d Z# G d d          Z$ G d de$          Z% G d de$          Z& G d de$          Z' G d de$          Z(e(e(e(e&e'e%dZ) G d de          Z*dS )ae  
sqldiff.py - Prints the (approximated) difference between models and database

TODO:
 - better support for relations
 - better support for constraints (mainly postgresql?)
 - support for table spaces with postgresql
 - when a table is not managed (meta.managed==False) then only do a one-way
   sqldiff ? show differences from db->table but not the other way around since
   it's not managed.

KNOWN ISSUES:
 - MySQL has by far the most problems with introspection. Please be
   carefull when using MySQL with sqldiff.
   - Booleans are reported back as Integers, so there's no way to know if
     there was a real change.
   - Varchar sizes are reported back without unicode support so their size
     may change in comparison to the real length of the varchar.
   - Some of the 'fixes' to counter these problems might create false
     positives or false negatives.
    N)DictUnionCallableOptional)apps)BaseCommandCommandError)OutputWrapper)no_style)
connectiontransactionmodels)UniqueConstraint)	AutoFieldIntegerField)normalize_together)signalcommand_orderT)nullc                 l   t          |           }t          |           } d}|t          |           k     rwt          | |         |          rI| |         s|                     |           |dz  }n&| |         | ||dz   <   t          | |         |          I|dz  }|t          |           k     w ||           S )Nr      )typelistlen
isinstancepop)lstltypesltypeis       q/var/www/html/e360mart/e360mart_env/lib/python3.11/site-packages/django_extensions/management/commands/sqldiff.pyflattenr"   *   s    IIE
s))C	A
c#hh,,Q(( 	&q6 &


Q"1vAa!eG Q(( 	& 	
Q c#hh,, 5::    c                     g }| j         r2| j        D ])}|                    t          |j                             *n=| j        D ]5}|                    t                    }| |                    |           6|S Nr   )	proxyparentsextendall_local_fields_metalocal_fieldsdb_typer   append)meta
all_fieldsparentfcol_types        r!   r*   r*   :   s    Jz !l 	> 	>F.v|<<====	> " 	! 	!AyyJy77Ha    r#   c                      e Zd Zi ZdgZg dZddddddd	d
ddddddd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d$ Zd% Zd& Zd' Zd( Zd) Zd* Z d+ Z!dCd,Z"dDd-Z#d. Z$d/ Z%d0 Z&d1 Z'd2 Z(d3 Z)d4 Z*dEd5Z+d6 Z,d7 Z-d8 Z.d9 Z/d: Z0dEd;Z1dEd<Z2d= Z3d> Z4d? Z5 e6            fd@Z7dA Z8dB Z9d!S )FSQLDiffdjango_migrationserrorcommenttable-missing-in-dbtable-missing-in-modelfield-missing-in-dbfield-missing-in-modelfkey-missing-in-dbzfkey-missing-in-modelindex-missing-in-dbindex-missing-in-modelunique-missing-in-dbunique-missing-in-modelfield-type-differfield-parameter-differnotnull-differzerror: %(0)szcomment: %(0)sz!table '%(0)s' missing in databaseztable '%(0)s' missing in modelsz6field '%(1)s' defined in model but missing in databasez6field '%(1)s' defined in database but missing in modelzBfield '%(1)s' FOREIGN KEY defined in model but missing in databasezBfield '%(1)s' FOREIGN KEY defined in database but missing in modelzJfield '%(1)s' INDEX named '%(2)s' defined in model but missing in databasezCfield '%(1)s' INDEX defined in database schema but missing in modelzKfield '%(1)s' UNIQUE named '%(2)s' defined in model but missing in databasezDfield '%(1)s' UNIQUE defined in database schema but missing in modelz9field '%(1)s' not of same type: db='%(3)s', model='%(2)s'z:field '%(1)s' parameters differ: db='%(3)s', model='%(2)s'z?field '%(1)s' null constraint should be '%(2)s' in the databasec                 b                        d          d                     ||d                             d                     d          d                     ||d                             dd                    fdt	          |dd                    D                       d	
S )
NALTER TABLE r   
	
ADD COLUMNr   c              3   ~   K   | ]7\  }}|d k    r                     |          n                    |          V  8dS r   NSQL_COLTYPESQL_KEYWORD.0r    astyles      r!   	<genexpr>z#SQLDiff.<lambda>.<locals>.<genexpr>w   Q      jjdaQRa""1%%%U5F5Fq5I5Ijjjjjjr#      ;)rO   	SQL_TABLE	SQL_FIELDjoin	enumerateselfrS   qnargss    `  r!   <lambda>zSQLDiff.<lambda>r   s    -((((47$$$$,''''47$$$$jjjjV_`defegeg`hViVijjjjjjj= r#   c                     |                     d          d|                     ||d                             d|                     d          d|                     ||d                             dS )NrG   rH   r   rI   zDROP COLUMNr   rW   rO   rX   rY   r\   s       r!   r`   zSQLDiff.<lambda>y   sz    -((((47$$$$-((((47$$$$	@ r#   c                 `                        d          d                     ||d                             d                     d          d                     ||d                             dd                    fdt	          |dd                    D                       d                     d	          d                     ||d
                             d                     ||d                             dt
          j                                        dS )NrG   rH   r   rI   rJ   r   c              3   ~   K   | ]7\  }}|d k    r                     |          n                    |          V  8dS rL   rM   rP   s      r!   rT   z#SQLDiff.<lambda>.<locals>.<genexpr>   rU   r#      
REFERENCESrV    (   )rW   )rO   rX   rY   rZ   r[   r   opsdeferrable_sqlr\   s    `  r!   r`   zSQLDiff.<lambda>   s*   -((((47$$$$,''''47$$$$jjjjV_`defegeg`hViVijjjjjjj,''''47$$$$47$$$$%%''''
< r#   c                    |                     d          d|                     |d                             d|                     d          d|                     |d                             d|                    d                    fd	|d
         D                                 |                     |d                   dS )NzCREATE INDEXrH   rV   rI   ONr   rg   , c              3   .   K   | ]} |          V  d S N rQ   er^   s     r!   rT   z#SQLDiff.<lambda>.<locals>.<genexpr>   +      !9!9A""Q%%!9!9!9!9!9!9r#   r   rh   );rO   rX   rY   rZ   r\   s     ` r!   r`   zSQLDiff.<lambda>   s    .))))47$$$$$DG!=!=!=!=		!9!9!9!9a!9!9!999:::$q'""""= r#   c                 |    |                     d          d|                     ||d                             dS )Nz
DROP INDEXrH   r   rW   rO   rX   r\   s       r!   r`   zSQLDiff.<lambda>   sB    ,''''47$$$$@ r#   c                    |                     d          d|                     |d                             d|                     d          d|                     |d                             d|                     d          d|                    d	                    fd
|d         D                                 dS )NrG   rH   r   rI   zADD CONSTRAINTrV   UNIQUErg   rn   c              3   .   K   | ]} |          V  d S rp   rq   rr   s     r!   rT   z#SQLDiff.<lambda>.<locals>.<genexpr>   rt   r#   r   ru   rv   r\   s     ` r!   r`   zSQLDiff.<lambda>   s    -((((47$$$$*++++47$$$$(####		!9!9!9!9a!9!9!999::::> r#   c                    |                     d          d|                     ||d                             d|                     d          d|                     d          d|                     ||d                             d
S )	NrG   rH   r   rI   DROP
CONSTRAINTr   rW   rx   r\   s       r!   r`   zSQLDiff.<lambda>   s    -((((47$$$$&!!!!,''''47$$$$A r#   c                 *   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                    |d                   d
S 	NrG   rH   r   rI   MODIFYr   rV   rW   rO   rX   rY   rN   r\   s       r!   r`   zSQLDiff.<lambda>   s    -((((47$$$$(####47$$$$$q'""""; r#   c                 *   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                    |d                   d
S r   r   r\   s       r!   r`   zSQLDiff.<lambda>   s    -((((47$$$$(####47$$$$$q'""""@ r#   c                 V   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                     |d                   d|                     d          d	S )
NrG   rH   r   rI   r   r   rV   NOT NULLrW   rb   r\   s       r!   r`   zSQLDiff.<lambda>   s    -((((47$$$$(####47$$$$$q'""""*%%%%8 r#   c                 d    |                     d|                    |d                   z            S )Nz-- Error: %sr   )NOTICEERRORr\   s       r!   r`   zSQLDiff.<lambda>   s*    ell>EKKX\]^X_L`L`;`.a.a r#   c                 d    |                     d|                    |d                   z            S )Nz-- Comment: %sr   )r   rX   r\   s       r!   r`   zSQLDiff.<lambda>   s.    =MPUP_P_`def`gPhPh=h0i0i r#   c                 >    |                     d|d         z            S )Nz-- Table missing: %sr   r   r\   s       r!   r`   zSQLDiff.<lambda>   s    ELLI_bfghbiIi<j<j r#   c                 >    |                     d|d         z            S )Nz-- Model missing for table: %sr   r   r\   s       r!   r`   zSQLDiff.<lambda>   s    u||LlostuovLv?w?w r#   FNc                    d | _         || _        || _        |d         | _        || _        || _        t          j        | _        g | _        i | _	        t                      | _        i | _        t                      | _        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        | j        d| _        d S )Ndense_outputr7   )has_differences
app_modelsoptionsdensestdoutstderrr   introspectiondifferencesunknown_db_fieldssetnew_db_fieldsr   unsigned	SQL_ERRORSQL_COMMENTSQL_TABLE_MISSING_IN_DBSQL_TABLE_MISSING_IN_MODELSQL_FIELD_MISSING_IN_DBSQL_FIELD_MISSING_IN_MODELSQL_FKEY_MISSING_IN_DBSQL_INDEX_MISSING_IN_DBSQL_INDEX_MISSING_IN_MODELSQL_UNIQUE_MISSING_IN_DBSQL_UNIQUE_MISSING_IN_MODELSQL_FIELD_TYPE_DIFFERSQL_FIELD_PARAMETER_DIFFERSQL_NOTNULL_DIFFERDIFF_SQL)r]   r   r   r   r   s        r!   __init__zSQLDiff.__init__   s    #$^,
'5!# UU	 ^'#'#?&*&E#'#?&*&E"&"=%)%D#'#?&*&E$($A'+'G!%!;&*&E"5
 
r#   c                 X   t          j                    | _        | j                            | j        d                   | _        d | j                            | j                  D             | _        | j        r| 	                                 | j
        r|                                  d S d S )Nonly_existing)r   c                     g | ]	}|j         
S rq   name)rQ   
table_infos     r!   
<listcomp>z SQLDiff.load.<locals>.<listcomp>   s    kkkj*/kkkr#   )r   cursorr   django_table_namesr   django_tablesget_table_list	db_tablescan_detect_notnull_differ	load_nullcan_detect_unsigned_differload_unsignedr]   s    r!   loadzSQLDiff.load   s     '))!/BBQUQ]^mQnBookkD<N<]<]^b^i<j<jkkk) 	NN* 	!     	! 	!r#   c                      t          d          )Nzcload_null functions must be implemented if diff backend has 'can_detect_notnull_differ' set to TrueNotImplementedErrorr   s    r!   r   zSQLDiff.load_null   s    !  #H  I  I  	Ir#   c                      t          d          )Nzgload_unsigned function must be implemented if diff backend has 'can_detect_unsigned_differ' set to Truer   r   s    r!   r   zSQLDiff.load_unsigned   s    !  #L  M  M  	Mr#   c                 @    | j                             ||g f           d S rp   )r   r.   )r]   	app_label
model_names      r!   add_app_model_markerzSQLDiff.add_app_model_marker   s&    J ;<<<<<r#   c                 |    || j         v s
J d            | j        d         d                             ||f           d S )NzUnknown difference type)
DIFF_TYPESr   r.   )r]   	diff_typer_   s      r!   add_differencezSQLDiff.add_difference   sJ    DO+++-F+++R ''D(9:::::r#   c                     | j         S rp   )DATA_TYPES_REVERSE_OVERRIDEr   s    r!   get_data_types_reverse_overridez'SQLDiff.get_data_types_reverse_override   s    //r#   c                     |S rp   rq   r]   field_namess     r!   format_field_nameszSQLDiff.format_field_names  s    r#   c                 n   t          j                    }|                    ||           d |j        D             }|                     |          }g }|                                D ]N}g }t          ||          D ]}|                    |           |                    t          |                     O|S )z
        Execute query and return a dict

        sql_to_dict(query, param) -> list of dicts

        code from snippet at https://www.djangosnippets.org/snippets/1383/
        c                     g | ]
}|d          S r   rq   )rQ   r   s     r!   r   z'SQLDiff.sql_to_dict.<locals>.<listcomp>  s    ===$d1g===r#   )	r   r   executedescriptionr   fetchallzipr.   dict)	r]   queryparamr   
fieldnamesresultrowrowsetfields	            r!   sql_to_dictzSQLDiff.sql_to_dict  s     "$$ue$$$==&*<===
,,Z88
??$$ 	( 	(CFZ-- % %e$$$$MM$v,,''''r#   c                 8    |                     t                    S r%   )r-   r   )r]   r   s     r!   get_field_model_typezSQLDiff.get_field_model_type  s    }}
}333r#   c                     i S rp   rq   )r]   current_kwargsr   r   
table_namereverse_types         r!   get_field_db_type_kwargsz SQLDiff.get_field_db_type_kwargs      	r#   c           	         |d         }|                                  }||v r	||         }n	 | j                            ||          }n# t          $ rr |                     |          }|sX| j        d         d d         |d d         f}|| j        vr-d| j        |<   |                     dd|d         d|d           Y d S Y nw xY wt          |          r
 |            }i }t          |t                    r#|                    |d	                    |d
         }|dk    r|rt          |dd           dk    rd}t          |t                    r#|                    |d                    |d         }|dk    r|d         r|d         |d<   |dk    r3|d         |d<   |d         rt          |d                   p|d         |d<   |d         rd|d<   |dvrd|d<   |rt          |dd          rd|d<   |dk    rB|d         }	| j                            ||	          \  }}
|
r|                    |
           d|z  }|                     |||||          }|                    |           |                     |          } |d#i |                    t&                     }|j        }|sd!}|||j        f| j        v r| j        |vr|d"| j        }|S )$Nr   r   rV   r9   z!Unknown database type for field 'r   z' (ri   kwargsr   i2B  	geom_typePOINTz.django.contrib.gis.db.models.fields.PointField	CharFieldrh   
max_lengthDecimalFieldre   
max_digits   decimal_places   Tblank)	TextFieldr   r   	geographyFGeometryFieldz&django.contrib.gis.db.models.fields.%sr&   publicrH   rq   )r   r   get_field_typeKeyErrorget_field_db_type_lookupr   r   r   callabler   r   updategetattrtupleabsget_geometry_typer   get_field_classr-   r   db_tablespacecolumnr   unsigned_suffix)r]   r   r   r   	type_coder   r   keyr   geo_col
geo_paramsextra_kwargsfield_classfield_db_type
tablespaces                  r!   get_field_db_typezSQLDiff.get_field_db_type   s     N	&*&J&J&L&L#3336yALL
 #1@@KXX      #<<YGG#  +B/3[!_EC$"88867.s3++IIfqrsftftftvvv  8A  B  B  B44     L!! 	*'<>>LlD)) 	0MM,x0111'/L%GE;,M,MQX,X,XKLlE** 	+MM,q/***'?L;&&;q>&#.q>F< >))#.q>F< '21~'M#k!n:M:M'_Q\]^Q_F#$q> 	&"F7O#===!%v 	'WUK77 	'"&F;?**!!nG (,'9'K'KJX_'`'`$L* *j)))ClRL44V[%Q[]ijjl###**<88#--f--555LL(
 	"!J
EL1T]BBtG[cpGpGp'4}}d6J6JKMs   A A6CCc                     d S rp   rq   )r]   r  s     r!   r   z SQLDiff.get_field_db_type_lookupj  s    tr#   c                     d|v r=|                     dd          \  }}t          j        |          }t          ||          S t          t          |          S )N.r   )rsplit	importlibimport_moduler   r   )r]   
class_pathmodule_pathpackage_namemodules        r!   r  zSQLDiff.get_field_classm  sW    *(2(9(9#q(A(A%K,[99F6<000vz***r#   c                 x    |j         }|dk    rd}|j        p|j        }| j                            |||fd          S )N r   fixme)r  	db_columnattnamer   get)r]   r   r   r  r  s        r!   get_field_db_nullablezSQLDiff.get_field_db_nullableu  sE    (
!J/2U]y}}j*g>HHHr#   c                     |rL|dk    rF|                     d          d                              d          d                                         S |S )Nzdouble precisionrH   r   ()splitlower)r]   
field_types     r!   strip_parameterszSQLDiff.strip_parameters|  sT     	B*(:::##C((+11#66q9??AAAr#   c                     t          t          |j                            }|j        D ]}|                    |j                   |                     ||          S rp   )r   r   index_togetherindexesr.   fieldsexpand_together)r]   r/   indexes_normalizedidxs       r!   get_index_togetherzSQLDiff.get_index_together  s]    !"4T5H"I"IJJ< 	2 	2C%%cj1111##$6===r#   c                     t          t          |j                            }|j        D ]1}t	          |t
                    r|                    |j                   2|                     ||          S rp   )	r   r   unique_togetherconstraintsr   r   r.   r)  r*  )r]   r/   unique_normalized
constraints       r!   get_unique_togetherzSQLDiff.get_unique_together  sp     !3D4H!I!IJJ* 	< 	<J*&677 <!(():;;;##$5t<<<r#   c                     g }t          |          D ]0}|                    t          fd|D                                  1|S )Nc              3   L   K   | ]}                     |          j        V  d S rp   )	get_fieldr  )rQ   r   r/   s     r!   rT   z*SQLDiff.expand_together.<locals>.<genexpr>  s2      HHdnnU++3HHHHHHr#   )r   r.   r   )r]   togetherr/   new_togetherr)  s     `  r!   r*  zSQLDiff.expand_together  sd    (22 	 	FHHHHHHHHH    r#   c                    t          j        t                     }t          |          D ]@}|r
|j        |v r|j        r)|j        r!|j        p|j        |                    i                               d          }|s/|r-t          fd|	                                D                       }|v r|r|
                    |g          }	|                     d|g|	dz              |                    t                     }
|
                    d          r|                     d|g|	dz   d	           |
                    d
          r|                     d|g|	dz   d           B|                     |          }t          d |                                D                       }|D ]?}||v r|r||v r|
                    ||          }	|                     d|||	dz              @d S )Nuniquec              3   H   K   | ]\  }}g|d          k    |d         V  dS columnsr:  Nrq   rQ   contraint_namer2  r  s      r!   rT   z4SQLDiff.find_unique_missing_in_db.<locals>.<genexpr>  {        *b  *bC]>S]  @G  H  LV  W`  La  a  a*X*>  a  a  a  a  *b  *br#   rA   _uniqr&   varcharr?   _like varchar_pattern_opstext text_pattern_opsc                 >    g | ]}|d          
|d         |d         S )r:  indexr=  rq   rQ   vs     r!   r   z5SQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  sT      0D  0D  0Ddefndo  0Dxy  {B  yC  0D)  0D  0D  0Dr#   r   SchemaEditorClassr*   r  r:  managedr  r  anyitems_create_index_namer   r-   
startswithr3  r   valuesr]   r/   table_indexestable_constraintsr   	skip_listschema_editorr   db_field_unique
index_namer-   r/  db_unique_columnsunique_columnsr  s                 @r!   find_unique_missing_in_dbz!SQLDiff.find_unique_missing_in_db  s   "4Z@@%d++ 	A 	AE U]i77| A A/:U]"/"3"3GR"@"@"D"DX"N"N& b+< b&)  *b  *b  *b  *baraxaxazaz  *b  *b  *b  'b  'bOm+++*==j7)TT
##$:J	S]`gSghhh--:->>%%i00 D''(=zG9V`cjVj  mC  D  D  D%%f-- A''(=zG9V`cjVjl  A  A  A22488.  0D  0DFWF^F^F`F`  0D  0D  0D  E  E- 		j 		jN!222 ^y88&99*nUUJ 6
NT^ahThiiii		j 		jr#   c                    t          d t          |          D                       }|                     |          }|                                D ]\  }}|d         s|d         r|d         }	t	          |	          dk    r'|                    |	d                   }
|
n|
j        rXnt          |	          |v rk|                     d||           d S )Nc                      g | ]}|j         |fS rq   r  rQ   r   s     r!   r   z8SQLDiff.find_unique_missing_in_model.<locals>.<listcomp>      QQQe,QQQr#   r:  rH  r=  r   r   rB   )	r   r*   r3  rO  r   r  r:  r   r   )r]   r/   rT  rU  r   r)  r/  constraint_namer2  r=  r   s              r!   find_unique_missing_in_modelz$SQLDiff.find_unique_missing_in_model  s   QQ:J4:P:PQQQRR22488+<+B+B+D+D 	X 	X'OZh' '"  +G7||q  

71:..=\  >>_44 9:WWWW%	X 	Xr#   c                 R   t          j        t                     }t          |          D ]}|j        r|j        p|j        }||vr|                    ||g          }|                     d||g|d           |                    t                     }	|		                    d          r|                     d||g|dz   d           |		                    d          r|                     d||g|dz   d           | 
                    |          }
t          d	 |                                D                       }|
D ]9}||v r|                    ||          }|                     d|||d
z   d           :|j        D ].}|j        |vr#|                     d||j        |j        d           /d S )Nr?   r  r&   rB  rC  rD  rE  rF  c                 >    g | ]}|d          
|d         |d         S )rH  r:  r=  rq   rI  s     r!   r   z4SQLDiff.find_index_missing_in_db.<locals>.<listcomp>  sT      0D  0D  0Ddefmdn  0Dwx  zB  xC  0D)  0D  0D  0Dr#   _idx)r   rL  r*   db_indexr  r  rP  r   r-   rQ  r-  r   rR  r(  r   r)  )r]   r/   rT  rU  r   rW  r   r  rY  r-   r'  db_index_togetherr=  rH  s                 r!   find_index_missing_in_dbz SQLDiff.find_index_missing_in_db  s3   "4Z@@%d++ 
	E 
	EE~ 	E/:U]-//!.!A!A*wi!X!XJ''(=zG9V`bdeee#mmzmBBG)))44 H++,A:PWyZdgnZn  qG  H  H  H))&11 E++,A:PWyZdgnZn  qD  E  E  E0066.  0D  0DFWF^F^F`F`  0D  0D  0D  E  E% 	e 	eG+++&99*gNNJ 5z7JY_L_acdddd\ 	e 	eEz!222##$9:u|UZU_acddd	e 	er#   c                    t          d t          |          D                       }d |j        D             }|                     |          }|                                D ][\  }}	||v r|	d         r	|	d         s|	d         }
|                    |
d                   }|	d         r|	d         s|nt          |
          dk    r|	d         r|j        ru|	d	         r"t          |t          j
                  r|j        r|	d         r|j        r|	d         r)|	d
         dk    r|	                    d          r|j        r|	d         r|j        r|	d         r|                    t                    rt!          |dd          r(n|	d         rt#          |
          |v rD|                     d||           ]d S )Nc                      g | ]}|j         |fS rq   r_  r`  s     r!   r   z7SQLDiff.find_index_missing_in_model.<locals>.<listcomp>  ra  r#   c                     g | ]	}|j         
S rq   r   rQ   r,  s     r!   r   z7SQLDiff.find_index_missing_in_model.<locals>.<listcomp>      ===CH===r#   r:  rH  r=  r   r   primary_keyforeign_keyr   r,  orderscheckr&   spatial_indexFr@   )r   r*   r(  r-  rO  r  r   ro  r   r   
ForeignKeydb_constraintr:  rg  db_checkr   r   r   r   )r]   r/   rT  rU  r   r)  meta_index_namesr'  rb  r2  r=  r   s               r!   find_index_missing_in_modelz#SQLDiff.find_index_missing_in_model  s0   QQ:J4:P:PQQQRR=====0066+<+B+B+D+D !	W !	W'OZ"222(# Jw,?  +GJJwqz**E8$ G)< W""m, 1B m, E6CT1U1U Z_Zm h' EL g& :f+=+F+F:>>ZbKcKc+Fhmht+F g& 5> g& 5>>Z>+P+P 5/599  g& 5>>^+K+K 8*oVVVVC!	W !	Wr#   c                 ^    |D ])}|d         |vr|                      d||d                    *d S )Nr   r=   )r   )r]   fieldmaptable_descriptionr   r   s        r!   find_field_missing_in_modelz#SQLDiff.find_field_missing_in_model  sL    $ 	R 	RC1vX%%##$<j#a&QQQ	R 	Rr#   c                    d |D             }|                                 D ]I\  }}||vr>g }|j        r_|                    |j        j        j        j        |j        j        j                            |j        j                  j        g           d}nd}|	                    |
                    t                               | j        d         rQ|                                r=|	                    d|                    |                                          z             |j        s|	                    d            | j        |||g|R   | j                            ||f           Kd S )Nc                     g | ]
}|d          S r   rq   rQ   r   s     r!   r   z4SQLDiff.find_field_missing_in_db.<locals>.<listcomp>  s    999SV999r#   r>   r<   r&   include_defaultsz
DEFAULT %sr   )rO  remote_fieldr)   modelr+   db_tabler6  
field_namer  r.   r-   r   r   has_defaultget_prep_valueget_defaultr   r   r   add)	r]   rz  r{  r   	db_fieldsr  r   field_outputops	            r!   find_field_missing_in_dbz SQLDiff.find_field_missing_in_db  s   99'8999	!)!1!1 	A 	AJ**!% / '');)A)G)PRWRdRjRpRzRz  |A  |N  |Y  SZ  SZ  Sa  )b  c  c  c-BB.B##EMMZM$H$HIII< 23 b8I8I8K8K b ''u7K7KEL]L]L_L_7`7`(`aaaz 4 ''
333##B
JNNNNN"&&
J'?@@@	A 	Ar#   c                    t          d |D                       }t          |          D ]}|j        |vr||j                 }|                     |          }|                     |||          }	|r |||||	          \  }}	|                     |	          |                     |          k    s|                     d||j        ||	           d S )Nc                 "    g | ]}|d          |fS r   rq   r  s     r!   r   z2SQLDiff.find_field_type_differ.<locals>.<listcomp>1       EEEC3q63-EEEr#   rC   )r   r*   r   r   r  r%  r   )
r]   r/   r{  r   funcr  r   r   
model_typer-   s
             r!   find_field_type_differzSQLDiff.find_field_type_differ0  s    EE3DEEEFF	%d++ 	f 	fEz**#EJ/K22599J,,[%LLG  T&*d5+z7&S&S#
G((11T5J5J:5V5VVV##$7UZQ[]deee	f 	fr#   c                    t          d |D                       }t          |          D ]+}|j        |vr||j                 }|                     |          }|                     |||          }	|                     |          |                     |	          k    ss|r |||||	          \  }}	|                    t                    d         }
d|	v rT|	                    dd          \  }	}|	                                
                    d                              d          }nd }||	k    r|
|k    s|                     d||j        ||	           -d S )	Nc                 "    g | ]}|d          |fS r   rq   r  s     r!   r   z7SQLDiff.find_field_parameter_differ.<locals>.<listcomp>B  r  r#   r&   rr  z CHECKr   r!  ri   rD   )r   r*   r   r   r  r%  db_parametersr   r"  striplstriprstripr   )r]   r/   r{  r   r  r  r   r   r  r-   model_checkrv  s               r!   find_field_parameter_differz#SQLDiff.find_field_parameter_differA  s   EE3DEEEFF	%d++ 	k 	kEz**#EJ/K22599J,,[%LLG((448M8Mg8V8VVV  T&*d5+z7&S&S#
G---DDWMK7""$+MM(A$>$>!#>>++22377>>sCC((x0G0G##$<j%*V`bijjj/	k 	kr#   c                     | j         sd S t          |          D ]`}|j        p|j        }||f| j        v r|                     ||          }|j        |k    r#|j        rdpd}|                     d|||           ad S )Nr}   SETrE   )r   r*   r  r  r   r  r   r   )r]   r/   r{  r   r   r  r   actions           r!   find_field_notnull_differz!SQLDiff.find_field_notnull_differ\  s    - 	F%d++ 	S 	SEo6GG$(:::--eZ@@DzT!!.7%##$4j'6RRR	S 	Sr#   c                     i S rp   rq   )r]   r   r   r   s       r!   get_constraintszSQLDiff.get_constraintsi  r   r#   c           	         | j         d         rH|                     d d            | j        D ]*}|| j        vr|| j        vr|                     d|           +d }| j        D ]}|j        }|j        }|j	        }| j         d         s|j
        r-||k    r|                     ||j                   || j        vr|                     d|           nt          | j        d          r!| j                            | j        |          }n!|                     | j        || j                  }t!          d t#          |          D                       }|j        r
t&          |d<   	 | j                            | j        |          }	nc# t*          $ rV}
|                     dd	t-          |
                                          z             t1          j                     Y d }
~
yd }
~
ww xY wi }|                                D ]O\  }}|d
         }t7          |          dk    r/|d         |d         |                    d          |d||d         <   P|                     ||||           |                     ||||           |                     ||	|           |                      ||	|           | !                    ||||           | "                    ||||           | #                    ||	|           | $                    ||	|           | %                    ||	|           tM          d | j'        D                       | _(        d S )Nall_applicationsr;   include_proxy_modelsr:   r  c                 H    g | ]}|j         p|                                |f S rq   )r  get_attnamer`  s     r!   r   z,SQLDiff.find_differences.<locals>.<listcomp>  s1    qqqQVeoD1B1B1D1DeLqqqr#   r   r8   zunable to introspect table: %sr=  r   ro  r:  r   )ro  r:  r   r?  r   c                 4    g | ]\  }}}t          |          S rq   )r   )rQ   
_app_label_model_namediffss       r!   r   z,SQLDiff.find_differences.<locals>.<listcomp>  s%    #f#f#f3Q:{ECJJ#f#f#fr#   ))r   r   r   r   IGNORE_MISSING_TABLESr   r   r+   r  r   r'   __name__hasattrr   r  r   r   r*   order_with_respect_toORDERING_FIELDget_table_description	Exceptionstrr  r   rollbackrO  r   r  rc  rx  r|  r  r\  ri  r  r  r  maxr   r   )r]   tablecur_app_label	app_modelr/   r   r   rU  rz  r{  rs   rT  r?  dctr=  s                  r!   find_differenceszSQLDiff.find_differencesl  s   <*+ 	I%%dD111 I I 222uDD^7^7^''(@%HHH F	P F	PI?DJI< 67 DJ 	)))))Y5GHHH//##$9:FFFt)+<== f$($6$F$Ft{T^$_$_!!$($8$8jRVRd$e$e!qqZjkoZpZpqqqrrH ) 4%3"$($6$L$LT[Zd$e$e!!   ##G-MPSTUPVPVP\P\P^P^-^___$&&& M'8'>'>'@'@ 	 	#i.w<<1$$'*='9"%h- #*8	1 1M'!*- --dMCTV`aaa,,T=BSU_```,,X7H*UUU ))(4EzRRR**4@QS]^^^))$?PR\]]] ''.?LLL,,T3DjQQQ**41BJOOOO"#f#fUYUe#f#f#fggs    E==
GAGGc                 x    | j         d         r|                     |           dS |                     |           dS )z Print differences to stdout sqlN)r   print_diff_sqlprint_diff_text)r]   rS   s     r!   
print_diffzSQLDiff.print_diff  sE    < 	(&&&&&  '''''r#   c                 P   | j         sG| j                                                d                     | j                            d           | j        sG| j                                                d                     | j                            d           d }| j        D ]\  }}}|s
| j        sO|rM||k    rG| j                                                d          d                    |                     |}| j        sG|rE| j                                                d          d                    |                     |D ]K}|\  }}| j        |         t          fdt          |          D                       z  }	d                    fd	t          |	                    d                    D                       }	| j        s3| j                                                d
          d|	           |rv| j                                                d          d                    |          d                    d          d                    |          d|		           1| j                            |	           Md S )NzE# Detecting notnull changes not implemented for this database backendr  zF# Detecting unsigned changes not implemented for this database backendz+ Application:rH   z|-+ Differences for model:c           	   3      K   | ]\\  }}t          |                              t          |t          t          f          rd                     |          n|          fV  ]dS )rn   N)r  rX   r   r   r   rZ   rQ   r    rs   rS   s      r!   rT   z*SQLDiff.print_diff_text.<locals>.<genexpr>  su       9 91 VVU__ZDRW==Y=Y-`TYYq\\\_`aab9 9 9 9 9 9r#   'c              3   ^   K   | ]'\  }}|d z  dk    r                     |          p|V  (dS )rV   r   N)r   r  s      r!   rT   z*SQLDiff.print_diff_text.<locals>.<genexpr>  sC      jjtq!A
 =u{{1~~ Bjjjjjjr#   z|--+AppModel)r   r   writer   r   r   r   rX   
DIFF_TEXTSr   r[   rZ   r"  )
r]   rS   r  r   r   r  diffr   	diff_argsrE  s
    `        r!   r  zSQLDiff.print_diff_text  s=   - 	"Kell+rsstttKb!!!. 	"Kell+sttuuuKb!!!,0,< 	0 	0(Iz5 : *) *0J0J!!U\\:J-K-K-K-KU__]fMgMgMg"hiii ): w* w!!U\\:V-W-W-W-WY^YhYhisYtYtYt"uvvv 0 0'+$	9y1D 9 9 9 9 )) 4 49 9 9 5 5  xxjjjjyY]YcYcdgYhYhOiOijjjjjz 0K%%f1E1E1E1Ett&LMMMM  0))ell5>Q>Q>Q>QSXSbSbclSmSmSmSmoto{o{  }D  pE  pE  pE  pE  GL  GV  GV  Wa  Gb  Gb  Gb  Gb  dh  dh  +i  j  j  j  j))$////0	0 	0r#   c           	         | j         sG| j                            |                    d                     | j                            d           d }t          j        j        }| j        s8| j        s/| j                            |	                    d                     d S d S | j                            |	                    d                     | j
        D ]\  }}}|s
| j        sK||k    rE| j                            |                    d|                    |          z                       |}| j        sE|rC| j                            |                    d|                    |          z                       |D ]V}|\  }}	 | j        |         |||	          }
| j        r|
                    dd          }
| j                            |
           W| j                            |	                    d	                     d S )
NzF-- Detecting notnull changes not implemented for this database backendr  z-- No differenceszBEGIN;z-- Application: %sz-- Model: %srI   rH   zCOMMIT;)r   r   r  r   r   rj   
quote_namer   r   rO   r   rX   r   replace)r]   rS   r  r^   r   r   r  r  r   r  rE  s              r!   r  zSQLDiff.print_diff_sql  s   - 	"Kell+sttuuuKb!!!^&# 	<: J!!%"3"34G"H"HIIIIIJ J Ke//99:::040@ , ,,	:u z .my&@&@K%%ell3G%//ZcJdJd3d&e&efff$-Mz bj bK%%ell>EOOT^D_D_3_&`&`aaa! , ,D+/(Iy34=3E2yIIDz 9#||FC88K%%d++++, Ke//	::;;;;;r#   )NNNNNrp   ):r  
__module____qualname__r   r  r   r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r  r   r  r  r%  r-  r3  r*  r\  rc  ri  rx  r|  r  r  r  r  r  r  r   r  r  r  rq   r#   r!   r5   r5   H   sz       "$ 	  J$  #B"CW"Zb!ek"g m#iX"^[ J$ " "
 
 " "   # # " "  baIiiKjj!w!w %!&O 
  
  
D
! 
! 
!I I IM M M= = =; ; ;0 0 0    (4 4 4   H H H HT  + + +I I I  
> > >= = =  "j "j "j "jHX X X0e e e4&W &W &WPR R R
A A A&f f f f"k k k k6S S S  Oh Oh Ohb  (xzz ( ( ( (0 0 0B< < < < <r#   r5   c                   "    e Zd ZdZdZd Zd ZdS )GenericSQLDiffFc                     d S rp   rq   r   s    r!   r   zGenericSQLDiff.load_null      r#   c                     d S rp   rq   r   s    r!   r   zGenericSQLDiff.load_unsigned	  r  r#   N)r  r  r  r   r   r   r   rq   r#   r!   r  r    s>         %!&      r#   r  c                   \     e Zd ZdZdZdZ fdZd Zd Zd Z	d Z
d fd		Zd
 ZddZ xZS )	MySQLDiffTUNSIGNEDc                     t                                                       t                      | _        |                                  d S rp   )superr   r   auto_incrementload_auto_incrementr]   	__class__s    r!   r   zMySQLDiff.load  s8    !ee  """""r#   c                     d |D             S )Nc                 6    g | ]}|                                 S rq   )r#  )rQ   r2   s     r!   r   z0MySQLDiff.format_field_names.<locals>.<listcomp>  s     ///a		///r#   rq   r   s     r!   r   zMySQLDiff.format_field_names  s    //;////r#   c                     d}| j         D ]=}|                     d|g          }|D ]!}|||d         f}|d         dk    | j        |<   ">d S )Nr   z
                SELECT column_name, is_nullable
                FROM information_schema.columns
                WHERE table_schema = DATABASE()
                    AND table_name = %scolumn_nameis_nullableYESr   r   r   r]   r  r   r   r   r  s         r!   r   zMySQLDiff.load_null  s    
. 	D 	DJ%% '+ .8L	: :F
 % D D
!:z-/HI!+M!:e!C	#D	D 	Dr#   c                     d}| j         D ]C}|                     d|g          }|D ]'}|||d         f}| j                            |           (Dd S )Nr   z
                SELECT column_name
                FROM information_schema.columns
                WHERE table_schema = DATABASE()
                    AND table_name = %s
                    AND column_type LIKE '%%unsigned'r  )r   r   r   r  r  s         r!   r   zMySQLDiff.load_unsigned&  s    
. 		' 		'J%% '9
 <F,H HF % ' '
!:z-/HI!!#&&&&'		' 		'r#   c                     | j         D ]B}|                     d|g          }|D ]&}||d         f}| j                            |           'Cd S )Nz
                SELECT column_name
                FROM information_schema.columns
                WHERE table_schema = DATABASE()
                   AND table_name = %s
                   AND extra = 'auto_increment'r  )r   r   r  r  )r]   r   r   r   r  s        r!   r  zMySQLDiff.load_auto_increment3  s    . 		- 		-J%% '3
 6@LB BF % - -
!:m#<=#'',,,,-		- 		-r#   Nc                    t                                          |||          }|sd S |r|                     |          }|                     |          dk    r.|                     |          dk    r|                    d          }|                     |          dk    r|dk    rd}||j        f| j        v r	d|vr|dz  }|S )NcharrB  varboolintegerAUTO_INCREMENTz AUTO_INCREMENT)r  r  r   r%  r  r  r  r]   r   r   r   r-   r$  r  s         r!   r  zMySQLDiff.get_field_db_typeB  s    ''++K
KK 	F 	-22599J $$Z00F::t?T?TU\?]?]aj?j?j!..// $$Z00F::i''$GEL)T-@@@EU]dEdEd,,r#   c                    t          d t          |          D                       }d |j        D             }|                     |          }|                     |          }|                                D ]\  }	}
|	|v r|
d         r	|
d         s|
d         }|                    |d                   }t          |          dk    r|s|                     d||	           l|
d	         r|j	        r||
d
         r"t          |t          j                  r|j        r|
d         r|j        r|
d         r)|
d         dk    r|
                    d          r|j        r|
d         r|j        r|
d         r|                    t"                    rt%          |dd          r/n>|
d         rt'          |          |v rK|
d         r|
d         rt'          |          |v rn|                     d||	           d S )Nc                      g | ]}|j         |fS rq   r_  r`  s     r!   r   z9MySQLDiff.find_index_missing_in_model.<locals>.<listcomp>Y  ra  r#   c                     g | ]	}|j         
S rq   r   rm  s     r!   r   z9MySQLDiff.find_index_missing_in_model.<locals>.<listcomp>Z  rn  r#   r:  rH  r=  r   r   r@   ro  rp  r   r,  rq  rr  r&   rs  F)r   r*   r(  r-  r3  rO  r  r   r   ro  r   r   rt  ru  r:  rg  rv  r   r   r   )r]   r/   rT  rU  r   r)  rw  r'  r/  rb  r2  r=  r   s                r!   rx  z%MySQLDiff.find_index_missing_in_modelX  sv   QQ:J4:P:PQQQRR=====006622488+<+B+B+D+D &	W &	W'OZ"222(# Jw,?  +GJJwqz**E 7||q   ''(@*o^^^m, 1B m, E6CT1U1U Z_Zm h' EL g& :f+=+F+F:>>ZbKcKc+Fhmht+F g& 5> g& 5>>Z>+P+P 5/599  g& 5>>^+K+Kg& :h+? E'NNVeDeDe 8*oVVVVM&	W &	Wr#   c                    t          j        t                     }t          |          D ]@}|r
|j        |v r|j        r)|j        r!|j        p|j        |                    i                               d          }|s/|r-t          fd|	                                D                       }|v r|r|
                    |g          }	|                     d|g|	dz              |                    t                     }
|
                    d          r|                     d|g|	dz   d	           |
                    d
          r|                     d|g|	dz   d           B|                     |          }t          d |                                D                       }|D ]?}||v r|r||v r|
                    ||          }	|                     d|||	dz              @d S )Nr:  c              3   H   K   | ]\  }}g|d          k    |d         V  dS r<  rq   r>  s      r!   rT   z6MySQLDiff.find_unique_missing_in_db.<locals>.<genexpr>  r@  r#   rA   rA  r&   rB  r?   rC  rD  rE  rF  c                 .    g | ]}|d          
|d         S r:  r=  rq   rI  s     r!   r   z7MySQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  (    /p/p/pdefndo/p)/p/p/pr#   rK  rS  s                 @r!   r\  z#MySQLDiff.find_unique_missing_in_db  s   "4Z@@%d++ 	A 	AE U]i77| A A/:U]"/"3"3GR"@"@"D"DX"N"N& b+< b&)  *b  *b  *b  *baraxaxazaz  *b  *b  *b  'b  'bOm+++*==j7)TT
##$:J	S]`gSghhh--:->>%%i00 D''(=zG9V`cjVj  mC  D  D  D%%f-- A''(=zG9V`cjVjl  A  A  A22488 //p/pFWF^F^F`F`/p/p/pqq- 	j 	jN!222 ^y88&99*nUUJ 6
NT^ahThiiii	j 	jr#   r  rp   )r  r  r  r   r   r  r   r   r   r   r  r  rx  r\  __classcell__r  s   @r!   r  r    s         $!% O# # # # #
0 0 0
D 
D 
D' ' '
- 
- 
-     ,,W ,W ,W\$j $j $j $j $j $j $j $jr#   r  c                   L     e Zd ZdZdZd Zd Zd
 fd	Zd Zd Z	d fd		Z
 xZS )SqliteSQLDiffTFc                     | j         D ]<}d}|                     d|z  g           D ]}|||d         f}|d          | j        |<   =d S )Nr   zPRAGMA table_info('%s');r   notnullr  )r]   r   r  r   r  s        r!   r   zSqliteSQLDiff.load_null  su    . 	; 	;J!J #../IJ/VXZ[[ ; ;
!:z&/AB%/	%:!:	#;	; 	;r#   c                     d S rp   rq   r   s    r!   r   zSqliteSQLDiff.load_unsigned  r  r#   Nc                    |g }d t          |          D             }|                                D ]N}|d         }t          |          dk    r1|d         }	|	|v r%|d         s|d         r|                    |	           O|                     |          }
t          d |                                D                       }|
D ]}||v r|                    |           t                                          |||||           d S )	Nc                 8    g | ]}|j         	|j        p|j        S rq   )r:  r  r  r`  s     r!   r   z;SqliteSQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  s*    oooubgbno%/:U]ooor#   r=  r   r   r:  ro  c                 .    g | ]}|d          
|d         S r  rq   rI  s     r!   r   z;SqliteSQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  r  r#   )rV  )r*   rR  r   r.   r3  r   r  r\  )r]   r/   rT  rU  r   rV  r[  r2  r=  r  r/  rZ  r  s               r!   r\  z'SqliteSQLDiff.find_unique_missing_in_db  s8   IooHXY]H^H^ooo+2244 	- 	-J +G7||q   ^++H1E+TaIb+$$V,,,22488./p/pFWF^F^F`F`/p/p/pqq- 	1 	1N!222  000))$?PR\hq)rrrrrr#   c                     d S rp   rq   r]   r/   rT  rU  r   s        r!   ri  z&SqliteSQLDiff.find_index_missing_in_db  r  r#   c                     d S rp   rq   r  s        r!   rx  z)SqliteSQLDiff.find_index_missing_in_model  r  r#   c                    t                                          |||          }|sd S |r\|                     |          }|                     |          dk    r.|                     |          dk    r|                    d          }|S )Nr  rB  r  )r  r  r   r%  r  r  s         r!   r  zSqliteSQLDiff.get_field_db_type  s    ''++K
KK 	4 	022599J$$Z00F::t?T?TU\?]?]aj?j?j!..//r#   rp   r  )r  r  r  r   r   r   r   r\  ri  rx  r  r  r  s   @r!   r  r    s         $!&; ; ;  s s s s s s0    	 	 	 	 	 	 	 	 	 	r#   r  c                        e Zd ZdZdZdddZdZdZd Zd Z	d	 Z
 fd
Zd Zd Zd Zd Zd Zd Zd fd	Zd Z xZS )PostgresqlSQLDiffTz*django.contrib.postgres.fields.HStoreField(django.contrib.postgres.fields.JSONField)hstorejsonba  
        SELECT nspname, relname, conname, attname, pg_get_constraintdef(pg_constraint.oid)
        FROM pg_constraint
        INNER JOIN pg_attribute ON pg_constraint.conrelid = pg_attribute.attrelid AND pg_attribute.attnum = any(pg_constraint.conkey)
        INNER JOIN pg_class ON conrelid=pg_class.oid
        INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace
        ORDER BY CASE WHEN contype='f' THEN 0 ELSE 1 END,contype,nspname,relname,conname;
    z
        SELECT nspname, relname, attname, attnotnull
        FROM pg_attribute
        INNER JOIN pg_class ON attrelid=pg_class.oid
        INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace;
    c                 V   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                     d          d|                    |d                   d	S 
NrG   rH   r   rI   ALTERr   TYPErV   rW   r   r\   s       r!   r`   zPostgresqlSQLDiff.<lambda>  s   UZUfUfgtUuUuUuUuw|  xG  xG  HJ  HJ  KO  PQ  KR  HS  HS  xT  xT  xT  xT  V[  Vg  Vg  ho  Vp  Vp  Vp  Vp  rw  rA  rA  BD  BD  EI  JK  EL  BM  BM  rN  rN  rN  rN  PU  Pa  Pa  bh  Pi  Pi  Pi  Pi  kp  k|  k|  }A  BC  }D  kE  kE  kE  kE  ;F r#   c                 V   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                     d          d|                    |d                   d	S r
  r   r\   s       r!   r`   zPostgresqlSQLDiff.<lambda>  s   Z_ZkZklyZzZzZzZz  }B  }L  }L  MO  MO  PT  UV  PW  MX  MX  }Y  }Y  }Y  }Y  [`  [l  [l  mt  [u  [u  [u  [u  w|  wF  wF  GI  GI  JN  OP  JQ  GR  GR  wS  wS  wS  wS  UZ  Uf  Uf  gm  Un  Un  Un  Un  pu  pA  pA  BF  GH  BI  pJ  pJ  pJ  pJ  @K r#   c                 V   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                     |d                   d|                     d          d	S )
NrG   rH   r   rI   zALTER COLUMNr   rV   r   rW   rb   r\   s       r!   r`   zPostgresqlSQLDiff.<lambda>  s   RWRcRcdqRrRrRrRrty  uD  uD  EG  EG  HL  MN  HO  EP  EP  uQ  uQ  uQ  uQ  SX  Sd  Sd  es  St  St  St  St  v{  vE  vE  FH  FH  IM  NO  IP  FQ  FQ  vR  vR  vR  vR  TY  Te  Te  fj  kl  fm  Tn  Tn  Tn  Tn  pu  pA  pA  BL  pM  pM  pM  pM  8N r#   c                 ~    t                                                       i | _        |                                  d S rp   )r  r   check_constraintsload_constraintsr  s    r!   r   zPostgresqlSQLDiff.load	  s4    !#r#   c                     |                      | j        g           D ]*}|d         |d         |d         f}|d          | j        |<   +d S )Nnspnamerelnamer  
attnotnull)r   SQL_LOAD_NULLr   r]   r  r  s      r!   r   zPostgresqlSQLDiff.load_null  s[    ##D$6;; 	3 	3Cy>3y>3y>BC!$\!22DIcNN	3 	3r#   c                     d S rp   rq   r   s    r!   r   zPostgresqlSQLDiff.load_unsigned  s	     	r#   c                     |                      | j        g           D ]-}|d         |d         |d         f}d|d         v r
|| j        |<   .d S )Nr  r  r  CHECKpg_get_constraintdef)r   SQL_LOAD_CONSTRAINTSr  r  s      r!   r  z"PostgresqlSQLDiff.load_constraints  se    ##D$=rBB 	2 	2Cy>3y>3y>BC#4555.1&s+	2 	2r#   c                 F    dd |                      |                      idS )Nz)django.contrib.postgres.fields.ArrayField
base_field)r   r   )r  )r]   r  s     r!   get_data_type_arrayfieldz*PostgresqlSQLDiff.get_data_type_arrayfield  s5    ?>d22:>>@@
 
 	
r#   c                      i ddd fdd fdd fdd	 fd
d fdd fdd fdd fdd fdd fdd fdd fdd fdd fdd fd d! fd" fd#d$d%d&S )'Ni  r   i  c                  0                          d          S )NBooleanFieldr  r  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>)      $77>7RR r#   i  c                  0                          d          S )NBinaryFieldr#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>*  s    $77=7QQ r#   i  c                  0                          d          S Nr   r#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>+      $77;7OO r#   i  c                  0                          d          S Nr   r#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>,  r%  r#   i  c                  0                          d          S r,  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>-  r%  r#   i  c                  0                          d          S r,  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>.  r%  r#   i  c                  0                          d          S r)  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>/  r*  r#   i  c                  0                          d          S r)  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>0  r*  r#   i  c                  0                          d          S r)  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>1  r*  r#   i  c                  0                          d          S )NBigIntegerFieldr#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>2  s    $77CT7UU r#   i  c                  0                          d          S N
FloatFieldr#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>3      $77<7PP r#   i  c                  0                          d          S r5  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>4  r7  r#   i  c                  0                          d          S r5  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>5  r7  r#   i[  c                  0                          d          S NDateTimeFieldr#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>6      $77?7SS r#   i  c                  0                          d          S r;  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>7  r=  r#   i  c                  0                          d          S )Nr   r#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>8  r%  r#   c                  0                          d          S )NDurationFieldr#  r$  r   s   r!   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>:  r=  r#   z0django.contrib.postgres.search.SearchVectorFieldr  )i  i  i  rq   r   s   `r!   r   z1PostgresqlSQLDiff.get_data_types_reverse_override&  s   
+
RRRR
 QQQQ
 OOOO	

 RRRR
 RRRR
 RRRR
 OOOO
 OOOO
 OOOO
 UUUU
 PPPP
 PPPP
 PPPP
 SSSS
  SSSS!
" RRRR#
& TSSSD<-
 
 
 	
r#   c           
         i }|                     dd|g           |                                D ]\  }}}}||vrwg |                                dk    |                                dv |                                dk    r)t          |d                             dd                    nd	d
d
d||<   ||         d                             |           |                     dd|g           |                                D ]6\  }}||vrg d
d
d	dd
d||<   ||         d                             |           7|                     d|g           |                                D ]$\  }	}
}}|	|vrt          |
          ||d	d
dd||	<   %|S )zm
        Find constraints for table

        Backport of django's introspection.get_constraints(...)
        a  
            SELECT
                kc.constraint_name,
                kc.column_name,
                c.constraint_type,
                array(SELECT table_name::text || '.' || column_name::text FROM information_schema.constraint_column_usage WHERE constraint_name = kc.constraint_name)
            FROM information_schema.key_column_usage AS kc
            JOIN information_schema.table_constraints AS c ON
                kc.table_schema = c.table_schema AND
                kc.table_name = c.table_name AND
                kc.constraint_name = c.constraint_name
            WHERE
                kc.table_schema = %s AND
                kc.table_name = %s
        r   primary key)rC  r:  zforeign keyr   r  r   NF)r=  ro  r:  rp  rr  rH  r=  a  
            SELECT kc.constraint_name, kc.column_name
            FROM information_schema.constraint_column_usage AS kc
            JOIN information_schema.table_constraints AS c ON
                kc.table_schema = c.table_schema AND
                kc.table_name = c.table_name AND
                kc.constraint_name = c.constraint_name
            WHERE
                c.constraint_type = 'CHECK' AND
                kc.table_schema = %s AND
                kc.table_name = %s
        Ta  
            SELECT
                c2.relname,
                ARRAY(
                    SELECT (SELECT attname FROM pg_catalog.pg_attribute WHERE attnum = i AND attrelid = c.oid)
                    FROM unnest(idx.indkey) i
                ),
                idx.indisunique,
                idx.indisprimary
            FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
                pg_catalog.pg_index idx
            WHERE c.oid = idx.indrelid
                AND idx.indexrelid = c2.oid
                AND c.relname = %s
        )r   r   r#  r   r"  r.   r   )r]   r   r   r   r0  r2  r  kind	used_colsrH  r=  r:  primarys                r!   r  z!PostgresqlSQLDiff.get_constraints@  s     	  
#	% 	% 	% 4:??3D3D 	> 	>/Ji,,!#'::<<=#@"jjll.GGHL

XeHeHe51););C)C)C#D#D#Dko""+ +J' 
#I.55f====  
#	% 	% 	% #)//"3"3 	> 	>J,,!#(##'!"+ +J' 
#I.55f====  \	 	 	 06/@/@ 		 		+E7FGK''#G}}#*$#'"!& &E" r#   Nc                    t                                          |||          }|sd S |rZ|                    d          r_|j        p|j        }|                     d||f          d         d         }|                    d          r|                    dd          }|S |j        r&t          |t                    r|dk    rd}n|d	k    rd
}|r|j        }|dk    rd}|j        p|j        }| j                            |||fi                               dd           }|rf|                    dd          }|                    dd          }d                    d |                    d          D                       }|d|z   z  }|S )Nz[]a`  SELECT attname, format_type(atttypid, atttypmod) AS type
                        FROM   pg_attribute
                        WHERE  attrelid = %s::regclass
                        AND    attname = %s
                        AND    attnum > 0
                        AND    NOT attisdropped
                        ORDER  BY attnum;
                    r   r   zcharacter varyingrB  r  serialbigint	bigserialr  r   r  z((r!  z))ri   z("c           	          g | ];}d |v r3d                     d |                    dd          D                       p|<S )ri   z" c              3   @   K   | ]}|                     d           V  dS )"N)r  )rQ   ps     r!   rT   zAPostgresqlSQLDiff.get_field_db_type.<locals>.<listcomp>.<genexpr>  s.      HoHoZ[QTHoHoHoHoHoHor#   rH   r   )rZ   r"  )rQ   rs   s     r!   r   z7PostgresqlSQLDiff.get_field_db_type.<locals>.<listcomp>  sh      2[  2[  2[yz#(2otyyHoHo_`_f_fgjlm_n_nHoHoHo?o?o2tst  2[  2[  2[r#   rH   )r  r  endswithr  r  r   rQ  r  ro  r   r   r  r  r  rZ   r"  )
r]   r   r   r   r-   r  introspect_db_typer  check_constraintr  s
            r!   r  z#PostgresqlSQLDiff.get_field_db_type  s   ''++K
KK 	F )	6%% *  /:U]%)%5%5  )
& 
& 
& 
&" &001DEE d);)C)CDWYb)c)c&))  *Zy%A%A *i''&GG(()G 6"0
##!)J/:U]#'#9#=#=z:W^>_ac#d#d#h#hi  BF  $G  $G # 6'7'?'?c'J'J$'7'?'?c'J'J$'+yy  2[  2[  O  U  U  VY  Z  Z  2[  2[  2[  (\  (\$s%555Gr#   c                     	 |                      d|g          d         d         }| j                            |                    d                    S # t          t
          f$ r Y d S w xY w)Nz-SELECT typname FROM pg_type WHERE typelem=%s;r   typname_)r   DATA_TYPES_REVERSE_NAMEr  r  
IndexErrorr   )r]   r  r   s      r!   r   z*PostgresqlSQLDiff.get_field_db_type_lookup  su    	##$SV_U`aabcdenoD/33DJJsOODDDH% 	 	 	DD	s   AA A'&A'r  )r  r  r  r   r   rU  r  r  r   r   r   r   r   r   r  r  r   r  r  r   r  r  s   @r!   r  r    s!        $!% ?; M F  F "K  "K N  N         
3 3 3
  
2 2 2
 
 

 
 
4Y Y Yf. . . . . .`     r#   r  )postgispostgresql_psycopg2
postgresqlmysqlsqlite3oraclec                   Z     e Zd ZdZdZ fdZ fdZed             Z fdZ	 fdZ
 xZS )Commanda  Prints the (approximated) difference between models and fields in the database for the given app name(s).

It indicates how columns in the database are different from the sql that would
be generated by Django. This command is not a database migration tool. (Though
it can certainly help) It's purpose is to show the current differences as a way
to check/debug ur models compared to the real database tables and columns.Fc                     t                                          |           |                    dd           |                    dddddd	
           |                    dddddd
           |                    dddddd           |                    dddddd           |                    ddddd           |                    ddddd           |                    d dd!dt          j                   d S )"Nr   *)nargsz--all-applicationsz-a
store_trueFr  z8Automaticly include all application from INSTALLED_APPS.)r  defaultdesthelpz--not-only-existingz-estore_falseTr   z_Check all tables that exist in the database, not only tables that should exist based on models.z--dense-outputz-dr   zRShows the output in dense format, normally output is spreaded over multiple lines.)r  rd  rc  re  z--output_textz-tr  z:Outputs the differences as descriptive text instead of SQLz--include-proxy-modelsr  z!Include proxy models in the graphz--include-defaultsr  z3Include default values in SQL output (beta feature)z--migrate-for-testsmigrate_for_tests)r  add_argumentsadd_argumentargparseSUPPRESS)r]   parserr  s     r!   rh  zCommand.add_arguments  s   f%%%Ks333 $|#K	 	 	
 	
 	
 	!4 r	 	 	
 	
 	
 	d<ne 	 	
 	
 	

 	T-eM 	 	
 	
 	

 	$\@V4 	 	
 	
 	

 	 <NF 	 	
 	
 	

 	!,=P" 	 	
 	
 	
 	
 	
r#   c                 H     t                      j        |i | d| _        d S )Nr   )r  r   	exit_code)r]   r_   r   r  s      r!   r   zCommand.__init__1  s*    $)&)))r#   c                    ddl m} |d         }d }t          |d          r|j        d         d         }n|j        }|dk    rt          d          |d	         rt          j        d
          }nz|st          d          t          |t          t          t          f          s|g}g }|D ]?}t          j        |          }|                    |                    d
                     @|st          d          |d         }	|	rddlm}
  |
dg|R d
d
d |s%t           j                            d          d         }d|v r|                    d          d         }t&                              |t*                    } |||| j        | j                  }|                                 |                                 |j        sd| _        |                    | j                   d S )Nr   )settingsr   	DATABASESrc  ENGINEdummyzDjango doesn't know which syntax to use for your SQL statements,
because you haven't specified the DATABASE_ENGINE setting.
Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.r  T)include_auto_createdzEnter at least one appname.z+Unable to execute sqldiff no models founds.rg  )call_commandmigrate)no_input
run_syncdbr  r   )r   r   )django.confrp  r  rq  DATABASE_ENGINEr	   r   
get_modelsr   r   r   r   get_app_configr)   django.core.managementru  r   r  r"  DATABASE_SQLDIFF_CLASSESr  r  r   r   r   r  r   rn  r  rS   )r]   r_   r   rp  
app_labelsenginer   r   
app_configrg  ru  clssqldiff_instances                r!   handlezCommand.handle5  sK   (((((([)
8[)) 	.'	28<FF-FW   a b b b %& 	TdCCCJJ B"#@AAAj4*<== *(\
J' T T	!0;;
!!*"7"7T"7"R"RSSSS 	NLMMM#$78 	Q;;;;;;LPZPP$4PPPP 	:*0055b9F&==\\#&&r*F&**6>BB3z74;t{[[[))+++/ 	DN##DJ/////r#   c                 \   	  t                      j        |i | d S # t          $ r}|d         r t          | dd           }|s$t	          t
          j        | j        j                  }|	                    |j
        j        d|           t          j        d           Y d }~d S d }~ww xY w)N	tracebackr   z: rV   )r  r   r	   r   r
   sysr   rS   r   r  r  r  exit)r]   r_   r   rs   r   r  s        r!   r   zCommand.executek  s    	EGGOT-W----- 		 		 		{#  T8T22F E&sz4:3CDDLLQ[%9%9%911=>>>HQKKKKKKKKK		s    
B+A8B&&B+c                 |    t                                          |           t          j        | j                   d S rp   )r  run_from_argvr  r  rn  )r]   argvr  s     r!   r  zCommand.run_from_argvy  s3    d###     r#   )r  r  r  re  output_transactionrh  r   r   r  r   r  r  r  s   @r!   r^  r^    s        ND '
 '
 '
 '
 '
R     30 30 ]30j    ! ! ! ! ! ! ! ! !r#   r^  )+__doc__r  r  rj  typingr   r   r   r   django.appsr   r~  r   r	   django.core.management.baser
   django.core.management.colorr   	django.dbr   r   r   django.db.modelsr   django.db.models.fieldsr   r   django.db.models.optionsr   "django_extensions.management.utilsr   r  r   r   r"   r*   r5   r  r  r  r  r  r^  rq   r#   r!   <module>r     s   ,     



  2 2 2 2 2 2 2 2 2 2 2 2       < < < < < < < < 5 5 5 5 5 5 1 1 1 1 1 1 5 5 5 5 5 5 5 5 5 5 - - - - - - ; ; ; ; ; ; ; ; 7 7 7 7 7 7 < < < < < <hT222 u       w
< w
< w
< w
< w
< w
< w
< w
<t    W   ]j ]j ]j ]j ]j ]j ]j ]j@; ; ; ; ;G ; ; ;|F F F F F F F FT !,#  }! }! }! }! }!k }! }! }! }! }!r#   