
    ]j                     p   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*y)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                    t        |       }t        |       } d}|t        |       k  rZt        | |   |      r7| |   s| j	                  |       |dz  }n| |   | ||dz    t        | |   |      r7|dz  }|t        |       k  rZ ||       S )Nr      )typelistlen
isinstancepop)lstltypesltypeis       W/root/env/lib/python3.12/site-packages/django_extensions/management/commands/sqldiff.pyflattenr"   *   s    IE
s)C	A
c#h,Q(q6
Q"1vAa!e Q( 	
Q c#h, :    c                    g }| j                   r7| j                  D ]&  }|j                  t        |j                               ( |S | j
                  D ],  }|j                  t              }||j                  |       . |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zzll 	>F.v||<=	>  "" 	!AyyJy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 Z9y!)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                 
   j                  d      dj                   ||d               dj                  d      dj                   ||d               ddj                  fdt	        |dd        D              d	
S )
NALTER TABLE r   
	
ADD COLUMNr   c              3   r   K   | ].  \  }}|d k(  rj                  |      nj                  |       0 ywr   NSQL_COLTYPESQL_KEYWORD.0r    astyles      r!   	<genexpr>z#SQLDiff.<lambda>.<locals>.<genexpr>w   7     jdaQRa""1%U5F5Fq5IIj   47   ;)rO   	SQL_TABLE	SQL_FIELDjoin	enumerateselfrS   qnargss    `  r!   <lambda>zSQLDiff.<lambda>r   sp    -(47$,'47$jV_`defeg`hVijj= r#   c                     |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               dS )NrG   rH   r   rI   zDROP COLUMNr   rX   rO   rY   rZ   r]   s       r!   ra   zSQLDiff.<lambda>y   sN    -(47$-(47$	@ r#   c                    j                  d      dj                   ||d               dj                  d      dj                   ||d               ddj                  fdt	        |dd        D              dj                  d	      dj                   ||d
               dj                   ||d               dt
        j                  j                         dS )NrG   rH   r   rI   rJ   r   c              3   r   K   | ].  \  }}|d k(  rj                  |      nj                  |       0 ywrL   rM   rP   s      r!   rT   z#SQLDiff.<lambda>.<locals>.<genexpr>   rU   rV      
REFERENCESrW    (   )rX   )rO   rY   rZ   r[   r\   r   opsdeferrable_sqlr]   s    `  r!   ra   zSQLDiff.<lambda>   s    -(47$,'47$jV_`defeg`hVijj,'47$47$%%'
< r#   c                 >   |j                  d      d|j                   |d               d|j                  d      d|j                   |d               d|j                  dj                  fd	|d
   D                    |j                  |d         dS )NzCREATE INDEXrH   rW   rI   ONr   rh   , c              3   .   K   | ]  } |        y wN rQ   er_   s     r!   rT   z#SQLDiff.<lambda>.<locals>.<genexpr>        !9A"Q%!9   r   ri   );rO   rY   rZ   r[   r]   s     ` r!   ra   zSQLDiff.<lambda>   s~    .)47$$DG!=		!9a!99:$q'"= r#   c                 `    |j                  d      d|j                   ||d               dS )Nz
DROP INDEXrH   r   rX   rO   rY   r]   s       r!   ra   zSQLDiff.<lambda>   s,    ,'47$@ r#   c                 :   |j                  d      d|j                   |d               d|j                  d      d|j                   |d               d|j                  d      d|j                  d	j                  fd
|d   D                    dS )NrG   rH   r   rI   zADD CONSTRAINTrW   UNIQUErh   ro   c              3   .   K   | ]  } |        y wrq   rr   rs   s     r!   rT   z#SQLDiff.<lambda>.<locals>.<genexpr>   ru   rv   r   rw   rx   r]   s     ` r!   ra   zSQLDiff.<lambda>   s|    -(47$*+47$(#		!9a!99:> r#   c                     |j                  d      d|j                   ||d               d|j                  d      d|j                  d      d|j                   ||d               d
S )	NrG   rH   r   rI   DROP
CONSTRAINTr   rX   rz   r]   s       r!   ra   zSQLDiff.<lambda>   s\    -(47$&!,'47$A r#   c                     |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               d|j                  |d         d
S 	NrG   rH   r   rI   MODIFYr   rW   rX   rO   rY   rZ   rN   r]   s       r!   ra   zSQLDiff.<lambda>   s_    -(47$(#47$$q'"; r#   c                     |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               d|j                  |d         d
S r   r   r]   s       r!   ra   zSQLDiff.<lambda>   s`    -(47$(#47$$q'"@ r#   c                    |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               d|j                  |d         d|j                  d      d	S )
NrG   rH   r   rI   r   r   rW   NOT NULLrX   rc   r]   s       r!   ra   zSQLDiff.<lambda>   sm    -(47$(#47$$q'"*%8 r#   c                 N    |j                  d|j                  |d         z        S )Nz-- Error: %sr   )NOTICEERRORr]   s       r!   ra   zSQLDiff.<lambda>   s$    ell>EKKX\]^X_L`;`.a r#   c                 N    |j                  d|j                  |d         z        S )Nz-- Comment: %sr   )r   rY   r]   s       r!   ra   zSQLDiff.<lambda>   s(    =MPUP_P_`def`gPh=h0i r#   c                 0    |j                  d|d   z        S )Nz-- Table missing: %sr   r   r]   s       r!   ra   zSQLDiff.<lambda>   s    ELLI_bfghbiIi<j r#   c                 0    |j                  d|d   z        S )Nz-- Model missing for table: %sr   r   r]   s       r!   ra   zSQLDiff.<lambda>   s    u||LlostuovLv?w r#   FNc                 H   d | _         || _        || _        |d   | _        || _        || _        t        j                  | _        g | _        i | _	        t               | _        i | _        t               | _        | j                  | j                  | j                   | j"                  | j$                  | j&                  | j(                  | j&                  | j*                  | j,                  | j.                  | j0                  | j2                  | j4                  | j6                  d| _        y )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5!# U	 ^^''#'#?#?&*&E&E#'#?#?&*&E&E"&"="=%)%D%D#'#?#?&*&E&E$($A$A'+'G'G!%!;!;&*&E&E"55
r#   c                    t        j                         | _        | j                  j                  | j                  d         | _        | j                  j                  | j                        D cg c]  }|j                   c}| _        | j                  r| j                          | j                  r| j                          y y c c}w )Nonly_existing)r   )r   cursorr   django_table_namesr   django_tablesget_table_listname	db_tablescan_detect_notnull_differ	load_nullcan_detect_unsigned_differload_unsigned)r^   
table_infos     r!   loadzSQLDiff.load   s     '')!//BBQUQ]Q]^mQnBo<@<N<N<]<]^b^i^i<jkj*//k))NN**  + ls   /Cc                     t        d      )Nzcload_null functions must be implemented if diff backend has 'can_detect_notnull_differ' set to TrueNotImplementedErrorr^   s    r!   r   zSQLDiff.load_null   s    !  #H  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r#   c                 @    | j                   j                  ||g f       y rq   )r   r.   )r^   	app_label
model_names      r!   add_app_model_markerzSQLDiff.add_app_model_marker   s    J ;<r#   c                 t    || j                   v sJ d       | j                  d   d   j                  ||f       y )NzUnknown difference type)
DIFF_TYPESr   r.   )r^   	diff_typer`   s      r!   add_differencezSQLDiff.add_difference   s=    DOO+F-FF+R ''D(9:r#   c                     | j                   S rq   )DATA_TYPES_REVERSE_OVERRIDEr   s    r!   get_data_types_reverse_overridez'SQLDiff.get_data_types_reverse_override   s    ///r#   c                     |S rq   rr   )r^   field_namess     r!   format_field_nameszSQLDiff.format_field_names  s    r#   c                 `   t        j                         }|j                  ||       |j                  D cg c]  }|d   	 }}| j	                  |      }g }|j                         D ]@  }g }t        ||      D ]  }	|j                  |	        |j                  t        |             B |S c c}w )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/
        r   )	r   r   executedescriptionr   fetchallzipr.   dict)
r^   queryparamr   r   
fieldnamesresultrowrowsetfields
             r!   sql_to_dictzSQLDiff.sql_to_dict  s     ""$ue$*0*<*<=$d1g=
=,,Z8
??$ 	(CFZ- %e$%MM$v,'		(
  >s   B+c                 .    |j                  t              S r%   )r-   r   )r^   r   s     r!   get_field_model_typezSQLDiff.get_field_model_type  s    }}
}33r#   c                     i S rq   rr   )r^   current_kwargsr   r   
table_namereverse_types         r!   get_field_db_type_kwargsz SQLDiff.get_field_db_type_kwargs      	r#   c           	         |d   }| j                         }||v r||   }n	 | j                  j                  ||      }t        |      r |       }i }t        |t              r|j                  |d	          |d
   }|dk(  r|rt        |dd       dk(  rd}t        |t              r|j                  |d          |d   }|dk(  r|d   r|d   |d<   |dk(  r'|d   |d<   |d   xr t        |d         xs |d   |d<   |d   rd|d<   |dvrd|d<   |rt        |dd      rd|d<   |dk(  r<|d   }	| j                  j                  ||	      \  }}
|
r|j                  |
       d|z  }| j!                  |||||      }|j                  |       | j#                  |      } |d#i |j%                  t&               }|j(                  }|sd!}|||j*                  f| j,                  v r| j.                  |vr|d"| j.                  }|S # t        $ ri | j	                  |      }|sR| j
                  d   d d |d d f}|| j                  vr+d| j                  |<   | j                  dd|d   d|d       Y y Y 5w xY w)$Nr   r   rW   r9   z!Unknown database type for field 'r   z' (rj   kwargsr   i2B  	geom_typePOINTz.django.contrib.gis.db.models.fields.PointField	CharFieldri   
max_lengthDecimalFieldrf   
max_digits   decimal_places   Tblank)	TextFieldr   r   	geographyFGeometryFieldz&django.contrib.gis.db.models.fields.%sr&   publicrH   rr   )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#336yAL
 #11@@KX L!'>LlD)MM,x01'/L%GE;,MQX,XKLlE*MM,q/*'?L;&;q>#.q>F< >)#.q>F< '21~'M#k!n:M'_Q\]^Q_F#$q>"F7O#==!%vWUK7"&F;?*!!nG (,'9'9'K'KJX_'`$L*j)ClRL44V[%Q[]ijl#**<8#-f-555L((
!J
ELL1T]]BtG[G[cpGp'4d6J6JKM}   #<<YG#++B/3[!_EC$"8"8867..s3++Ifqrsftv  8A  B $ s   H A,I32I3c                      y rq   rr   )r^   r  s     r!   r   z SQLDiff.get_field_db_type_lookupj  s    r#   c                     d|v r6|j                  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  sK    *(2(9(9#q(A%K,,[9F6<00vz**r#   c                     |j                   }|dk(  rd}|j                  xs |j                  }| 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  sH    ((
!J//2U]]yy}}j*g>HHr#   c                 |    |r9|dk7  r4|j                  d      d   j                  d      d   j                         S |S )Nzdouble precisionrH   r   ()splitlower)r^   
field_types     r!   strip_parameterszSQLDiff.strip_parameters|  sB    *(::##C(+11#6q9??AAr#   c                     t        t        |j                              }|j                  D ]  }|j	                  |j
                          | j                  ||      S rq   )r   r   index_togetherindexesr.   fieldsexpand_together)r^   r/   indexes_normalizedidxs       r!   get_index_togetherzSQLDiff.get_index_together  sT    !"4T5H5H"IJ<< 	2C%%cjj1	2 ##$6==r#   c                     t        t        |j                              }|j                  D ].  }t	        |t
              s|j                  |j                         0 | j                  ||      S rq   )	r   r   unique_togetherconstraintsr   r   r.   r%  r&  )r^   r/   unique_normalized
constraints       r!   get_unique_togetherzSQLDiff.get_unique_together  sc     !3D4H4H!IJ** 	<J*&67!(():):;	< ##$5t<<r#   c                 r    g }t        |      D ]%  }|j                  t        fd|D                     ' |S )Nc              3   T   K   | ]  }j                  |      j                   ! y wrq   )	get_fieldr  )rQ   r   r/   s     r!   rT   z*SQLDiff.expand_together.<locals>.<genexpr>  s      HdnnU+33Hs   %()r   r.   r   )r^   togetherr/   new_togetherr%  s     `  r!   r&  zSQLDiff.expand_together  s@    (2 	FHHH	 r#   c                    t        j                  t               }t        |      D ]-  }|r|j                  |v r|j                  s"|j
                  s/|j                  xs |j                  |j                  i       j                  d      }|s$|r"t        fd|j                         D              }|v r|r|j                  |g      }	| j                  d|g|	dz          |j                  t               }
|
j                  d      r| j                  d|g|	dz   d	       |
j                  d
      s| j                  d|g|	dz   d       0 | j                  |      }t        |j!                         D cg c]  }|d   s	|d   r|d    c}      }|D ]7  }||v r|r||v r|j                  ||      }	| j                  d|||	dz          9 y c c}w )Nuniquec              3   B   K   | ]  \  }}g|d    k(  s|d     ywcolumnsr6  Nrr   rQ   contraint_namer.  r  s      r!   rT   z4SQLDiff.find_unique_missing_in_db.<locals>.<genexpr>  L       *bC]>S]  @G  H  LV  W`  La  a*X*>  *b   
rA   _uniqr&   varcharr?   _like varchar_pattern_opstext text_pattern_opsindexr9  r   SchemaEditorClassr*   r  r6  managedr  r  anyitems_create_index_namer   r-   
startswithr/  r   valuesr^   r/   table_indexestable_constraintsr   	skip_listschema_editorr   db_field_unique
index_namer-   r+  vdb_unique_columnsunique_columnsr  s                  @r!   find_unique_missing_in_dbz!SQLDiff.find_unique_missing_in_db  s   "44Z@%d+ 	AEU]]i7||//:U]]"/"3"3GR"@"D"DX"N&+<&)  *baraxaxaz  *b  'bOm+*==j7)T
##$:J	S]`gSgh--:->%%i0''(=zG9V`cjVj  mC  D%%f-''(=zG9V`cjVjl  A%	A( 2248.FWF^F^F`  0Ddefndoxy  {B  yC)  0D  E- 		jN!22^y8&99*nUJ 6
NT^ahThi		j 0Ds   ?
G
GGc                    t        t        |      D cg c]  }|j                  |f c}      }| j                  |      }|j	                         D ]i  \  }}	|	d   s|	d   r|	d   }
t        |
      dk(  r$|j                  |
d         }|n|j                  rIt        |
      |v rW| j                  d||       k y c c}w )Nr6  rD  r9  r   r   rB   )
r   r*   r   r/  rI  r   r  r6  r   r   )r^   r/   rN  rO  r   r   r%  r+  constraint_namer.  r9  s              r!   find_unique_missing_in_modelz$SQLDiff.find_unique_missing_in_model  s    :J4:PQe,QR2248+<+B+B+D 	X'OZh''" +G7|q 

71:.=\\>_4 9:W%	X Rs   B=c                 l   t        j                  t               }t        |      D ]  }|j                  s|j                  xs |j
                  }||vs/|j                  ||g      }| j                  d||g|d       |j                  t               }	|	j                  d      r| j                  d||g|dz   d       |	j                  d      s| j                  d||g|dz   d        | j                  |      }
t        |j                         D cg c]  }|d	   s	|d
   r|d    c}      }|
D ]1  }||v r|j                  ||      }| j                  d|||dz   d       3 |j                  D ]:  }|j                  |vs| j                  d||j                  |j                  d       < y c c}w )Nr?   r  r&   r?  r@  rA  rB  rC  rD  r6  r9  _idx)r   rF  r*   db_indexr  r  rJ  r   r-   rK  r)  r   rL  r$  r   r%  )r^   r/   rN  rO  r   rQ  r   r  rS  r-   r#  rT  db_index_togetherr9  rD  s                  r!   find_index_missing_in_dbz SQLDiff.find_index_missing_in_db  s   "44Z@%d+ 
	EE~~//:U]]-/!.!A!A*wi!XJ''(=zG9V`bde#mmzmBG)))4++,A:PWyZdgnZn  qG  H))&1++,A:PWyZdgnZn  qD  E
	E 006.FWF^F^F`  0Ddefmdnwx  zB  xC)  0D  E% 	eG++&99*gNJ 5z7JY_L_acd		e \\ 	eEzz!22##$9:u||UZU_U_acd	e 0Ds   
F1F1#F1c                 V   t        t        |      D cg c]  }|j                  |f c}      }|j                  D cg c]  }|j                   }}| j                  |      }	|j                         D ])  \  }
}|
|v r|d   r|d   s|d   }|j                  |d         }|d   r|d   s|nt        |      dk(  r|d   r|j                  r]|d   r't        |t        j                        r|j                  r|d   r|j                  r|d   r&|d   d	k(  r|j                  d
      r|j                  r|d   r|j                  r|d   r|j!                  t"              rt%        |dd      r|d   rt'        |      |	v r| j)                  d||
       , y c c}w c c}w )Nr6  rD  r9  r   r   primary_keyforeign_keyr   r(  orderscheckr&   spatial_indexFr@   )r   r*   r   r$  r   r)  rI  r  r   ra  r   r   
ForeignKeydb_constraintr6  r]  db_checkr   r   r   r   )r^   r/   rN  rO  r   r   r%  r(  meta_index_namesr#  rY  r.  r9  s                r!   find_index_missing_in_modelz#SQLDiff.find_index_missing_in_model  s   :J4:PQe,QR04=CHH==006+<+B+B+D !	W'OZ"22(#Jw,? +GJJwqz*E8$G)<W"m,1B1Bm,E6CTCT1UZ_ZmZmh'ELLg&:f+=+F:>>ZbKchmhtht g&5>>g&5>>Z>+P5/59g&5>^+K 8*oVC!	W	 R=s
   F!F&c                 N    |D ]   }|d   |vs| j                  d||d          " y )Nr   r=   )r   )r^   fieldmaptable_descriptionr   r   s        r!   find_field_missing_in_modelz#SQLDiff.find_field_missing_in_model  s6    $ 	RC1vX%##$<j#a&Q	Rr#   c                 *   |D cg c]  }|d   	 }}|j                         D ]h  \  }}||vsg }|j                  r|j                  |j                  j                  j                  j
                  |j                  j                  j                  j                  |j                  j                        j                  g       d}	nd}	|j                  |j                  t                     | j                  d   rA|j                         r1|j                  d|j                  |j                               z         |j                   s|j                  d        | j"                  |	||g|  | j$                  j'                  ||f       k y c c}w )Nr   r>   r<   r&   include_defaultsz
DEFAULT %sr   )rI  remote_fieldr)   modelr+   db_tabler2  
field_namer   r.   r-   r   r   has_defaultget_prep_valueget_defaultr   r   r   add)
r^   rl  rm  r   r   	db_fieldsrt  r   field_outputops
             r!   find_field_missing_in_dbz SQLDiff.find_field_missing_in_db  s|   '89SV9	9!)!1 	AJ*!%% ''););)A)A)G)G)P)PRWRdRdRjRjRpRpRzRz  |A  |N  |N  |Y  |Y  SZ  Sa  Sa  )b  c-B.B##EMMZM$HI<< 238I8I8K ''u7K7KEL]L]L_7`(`azz ''
3###B
JNN""&&
J'?@	A :s   Fc                    t        |D cg c]	  }|d   |f c}      }t        |      D ]  }|j                  |vr||j                     }| j                  |      }	| j	                  |||      }
|r ||||	|
      \  }	}
| j                  |
      | j                  |	      k(  ry| j                  d||j                  |	|
        y c c}w )Nr   rC   )r   r*   r   r   r
  r!  r   )r^   r/   rm  r   funcr   ry  r   r   
model_typer-   s              r!   find_field_type_differzSQLDiff.find_field_type_differ0  s    3DEC3q63-EF	%d+ 	fEzz*#EJJ/K2259J,,[%LG &*5+z7&S#
G((1T5J5J:5VV##$7UZZQ[]de	f Fs   Cc                 t   t        |D cg c]	  }|d   |f c}      }t        |      D ]  }|j                  |vr||j                     }| j                  |      }	| j	                  |||      }
| j                  |	      | j                  |
      k(  sj|r ||||	|
      \  }	}
|j                  t              d   }d|
v rD|
j                  dd      \  }
}|j                         j                  d      j                  d      }nd }|	|
k(  r||k(  r| j                  d||j                  |	|
       	 y c c}w )	Nr   r&   rd  z CHECKr   r  rj   rD   )r   r*   r   r   r
  r!  db_parametersr   r  striplstriprstripr   )r^   r/   rm  r   r~  r   ry  r   r   r  r-   model_checkrh  s                r!   find_field_parameter_differz#SQLDiff.find_field_parameter_differA  s@   3DEC3q63-EF	%d+ 	kEzz*#EJJ/K2259J,,[%LG((48M8Mg8VV &*5+z7&S#
G---DWMK7"$+MM(A$>!#>>+2237>>sC(x0G##$<j%**V`bij/	k Fs   D5c                 (   | j                   sy t        |      D ]w  }|j                  xs |j                  }||f| j                  v r.| j                  ||      }|j                  |k7  sP|j                  xr dxs d}| j                  d|||       y y )Nr   SETrE   )r   r*   r  r  r   r  r   r   )r^   r/   rm  r   r   r  r   actions           r!   find_field_notnull_differz!SQLDiff.find_field_notnull_differ\  s    --%d+ 	SEoo6GG$(:(::--eZ@DzzT!.7%##$4j'6R	Sr#   c                     i S rq   rr   )r^   r   r   r   s       r!   get_constraintszSQLDiff.get_constraintsi  r   r#   c           
         | j                   d   rS| j                  d d        | j                  D ]2  }|| j                  vs|| j                  vs!| j                  d|       4 d }| j                  D ]d  }|j                  }|j                  }|j                  }| j                   d   s|j                  rD||k7  r| j                  ||j                         || j                  vr| j                  d|       t        | j                  d      r'| j                  j                  | j                  |      }n'| j                  | j                  || j                        }t!        t#        |      D cg c]"  }|j$                  xs |j'                         |f$ c}      }	|j(                  r	t*        |	d<   	 | j                  j-                  | j                  |      }
i }|j9                         D ];  \  }}|d	   }t;        |      d
k(  s|d   |d   |j=                  d      |d||d   <   = | j?                  ||||       | jA                  ||||       | jC                  |	|
|       | jE                  |	|
|       | jG                  ||||       | jI                  ||||       | jK                  ||
|       | jM                  ||
|       | jO                  ||
|       g tQ        | jR                  D cg c]  \  }}}t;        |       c}}}      | _*        y c c}w # t.        $ rK}| j                  ddt1        |      j3                         z         t5        j6                          Y d }~d }~ww xY wc c}}}w )Nall_applicationsr;   include_proxy_modelsr:   r  r   r8   zunable to introspect table: %sr9  r   ra  r6  r   )ra  r6  r   r;  r   )+r   r   r   r   IGNORE_MISSING_TABLESr   r   r+   rs  r   r'   __name__hasattrr   r  r   r   r*   r  get_attnameorder_with_respect_toORDERING_FIELDget_table_description	Exceptionstrr  r   rollbackrI  r   r  rZ  rj  rn  r|  rW  r_  r  r  r  maxr   r   )r^   tablecur_app_label	app_modelr/   r   r   rO  r   rl  rm  rt   rN  r;  dctr9  
_app_label_model_namediffss                      r!   find_differenceszSQLDiff.find_differencesl  sP   <<*+%%dD1 I 2 22uDD^D^7^''(@%HI  F	PI??DJI<< 67DJJ	))))Y5G5GH/##$9:Ft))+<=$($6$6$F$Ft{{T^$_!$($8$8jRVRdRd$e!ZjkoZpqQVeooD1B1B1DeLqrH ))%3"$($6$6$L$LT[[Zd$e! M'8'>'>'@ 	#i.w<1$'*='9"%h- #*8	1M'!*-		 --dMCTV`a,,T=BSU_`,,X7H*U ))(4EzR**4@QS]^))$?PR\] ''.?L,,T3DjQ**41BJOMF	PN  #UYUeUe#f#f3Q:{ECJ#fgc r  ##G-MPSTUPVP\P\P^-^_$$&R $gs%   -'L
1&L.M/	M,!A M''M,c                 h    | j                   d   r| j                  |       y| j                  |       y)z Print differences to stdout sqlN)r   print_diff_sqlprint_diff_text)r^   rS   s     r!   
print_diffzSQLDiff.print_diff  s*    <<&  'r#   c                    | j                   sE| j                  j                  j                  d             | j                  j                  d       | j                  sE| j                  j                  j                  d             | j                  j                  d       d }| j
                  D ]  \  }}}|s| j                  sG|rE||k7  r@| j                  j                  j                  d      dj                  |             |}| j                  s@|r>| j                  j                  j                  d      dj                  |             |D ]'  }|\  }}| j                  |   t        fdt        |      D              z  }	dj                  fd	t        |	j                  d            D              }	| j                  s0| j                  j                  j                  d
      d|	       |rg| j                  j                  j                  d      dj                  |      dj                  d      dj                  |      d|		       | j                  j                  |	       *  y )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   | ]J  \  }}t        |      j                  t        |t        t        f      rd j                  |      n|      f L yw)ro   N)r  rY   r   r   r   r[   rQ   r    rt   rS   s      r!   rT   z*SQLDiff.print_diff_text.<locals>.<genexpr>  sH      91 VU__ZDRW==YTYYq\_`ab9s   AA'c              3   b   K   | ]&  \  }}|d z  dk(  xr j                  |      xs | ( yw)rW   r   N)r   r  s      r!   rT   z*SQLDiff.print_diff_text.<locals>.<genexpr>  s2     jtq!A
 =u{{1~ B Bjs   ,/z|--+AppModel)r   r   writer   r   r   r   rY   
DIFF_TEXTSr   r\   r[   r  )
r^   rS   r  r   r   r  diffr   	diff_argsrB  s
    `        r!   r  zSQLDiff.print_diff_text  s,   --KKell+rstKKb!..KKell+stuKKb!,0,<,< 	0(Iz5::)0J!!U\\:J-KU__]fMg"hi )::*!!U\\:V-WY^YhYhisYt"uv 0'+$	9y1D 9 )) 49 5  xxjyY]YcYcdgYhOijjzzKK%%f1Et&LM ))ell5>QSXSbSbclSmoto{o{  }D  pE  GL  GV  GV  Wa  Gb  dh  +i  j))$/0	0r#   c           	      *   | j                   sE| j                  j                  |j                  d             | j                  j                  d       d }t        j
                  j                  }| j                  s8| j                  s+| j                  j                  |j                  d             y y | j                  j                  |j                  d             | j                  D ]  \  }}}|s
| j                  sC||k7  r>| j                  j                  |j                  d|j                  |      z               |}| j                  s>|r<| j                  j                  |j                  d|j                  |      z               |D ]W  }|\  }}	 | j                  |   |||	      }
| j                  r|
j                  dd      }
| j                  j                  |
       Y  | j                  j                  |j                  d	             y )
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   rk   
quote_namer   r   rO   r   rY   r   replace)r^   rS   r  r_   r   r   r  r  r   r  rB  s              r!   r  zSQLDiff.print_diff_sql  s   --KKell+stuKKb!^^&&##::!!%"3"34G"HI  KKe//9:040@0@ ,,	:uzzmy&@KK%%ell3G%//ZcJd3d&ef$-MzzjKK%%ell>EOOT^D_3_&`a! ,D+/(Iy34==3E2yIDzz#||FC8KK%%d+,, KKe//	:;r#   )NNNNNrq   ):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)  r/  r&  rW  rZ  r_  rj  rn  r|  r  r  r  r  r  r   r  r  r  rr   r#   r!   r5   r5   H   s   "$ 	J$  #B"CW"Zb!ek"g m#iX"^[J$"
" #" bIiKj!w %!&O 
D
!IM=;0(4HT+I
>="jHX0e4&WPR
A&f"k6SOhb  (z (0B<r#   r5   c                        e Zd ZdZdZd Zd Zy)GenericSQLDiffFc                      y rq   rr   r   s    r!   r   zGenericSQLDiff.load_null      r#   c                      y rq   rr   r   s    r!   r   zGenericSQLDiff.load_unsigned	  r  r#   N)r  r  r  r   r   r   r   rr   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               | _        | j	                          y rq   )superr   r   auto_incrementload_auto_incrementr^   	__class__s    r!   r   zMySQLDiff.load  s"    !e  "r#   c                 H    |D cg c]  }|j                          c}S c c}w rq   )r  )r^   r   r2   s      r!   r   zMySQLDiff.format_field_names  s    #./a	///s   c                     d}| j                   D ]9  }| j                  d|g      }|D ]  }|||d   f}|d   dk(  | j                  |<   ! ; y )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  ss    
.. 	DJ%% '+ .8L	:F
 % D
!:z-/HI!+M!:e!C		#D	Dr#   c                     d}| j                   D ]?  }| j                  d|g      }|D ]%  }|||d   f}| j                  j                  |       ' A y )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   rx  r  s         r!   r   zMySQLDiff.load_unsigned&  sl    
.. 		'J%% '9
 <F,HF % '
!:z-/HI!!#&'		'r#   c                     | j                   D ]>  }| j                  d|g      }|D ]$  }||d   f}| j                  j                  |       & @ y )Nz
                SELECT column_name
                FROM information_schema.columns
                WHERE table_schema = DATABASE()
                   AND table_name = %s
                   AND extra = 'auto_increment'r  )r   r   r  rx  )r^   r   r   r   r  s        r!   r  zMySQLDiff.load_auto_increment3  sg    .. 		-J%% '3
 6@LBF % -
!:m#<=##'',-		-r#   c                 D   t         |   |||      }|sy |r| j                  |      }| j                  |      dk(  r%| j                  |      dk(  r|j	                  d      }| j                  |      dk(  r|dk(  rd}||j
                  f| j                  v r	d|vr|dz  }|S )Ncharr?  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2259J $$Z0F:t?T?TU\?]aj?j!../ $$Z0F:i'$GELL)T-@-@@EU]dEd,,r#   c                    t        t        |      D cg c]  }|j                  |f c}      }|j                  D cg c]  }|j                   }}| j                  |      }	| j                  |      }
|j                         D ]K  \  }}||v r|d   r|d   s|d   }|j                  |d         }t        |      dk(  r|s| j                  d||       T|d   r|j                  rf|d   r't        |t        j                        r|j                  r|d   r|j                   r|d   r&|d	   d
k(  r|j                  d      r|j                   r|d   r|j"                  r|d   r|j%                  t&              rt)        |dd      r/|d   rt+        |      |	v r |d   r|d   rt+        |      |
v r9| j                  d||       N y c c}w c c}w )Nr6  rD  r9  r   r   r@   ra  rb  r   r(  rc  rd  r&   re  F)r   r*   r   r$  r   r)  r/  rI  r  r   r   ra  r   r   rf  rg  r6  r]  rh  r   r   r   )r^   r/   rN  rO  r   r   r%  r(  ri  r#  r+  rY  r.  r9  s                 r!   rj  z%MySQLDiff.find_index_missing_in_modelX  s   :J4:PQe,QR04=CHH==0062248+<+B+B+D &	W'OZ"22(#Jw,? +GJJwqz*E 7|q ''(@*o^m,1B1Bm,E6CTCT1UZ_ZmZmh'ELLg&:f+=+F:>>ZbKchmhtht g&5>>g&5>>Z>+P5/59g&5>^+Kg&:h+?E'NVeDe 8*oVM&	W R=s
   GGc                    t        j                  t               }t        |      D ]-  }|r|j                  |v r|j                  s"|j
                  s/|j                  xs |j                  |j                  i       j                  d      }|s$|r"t        fd|j                         D              }|v r|r|j                  |g      }	| j                  d|g|	dz          |j                  t               }
|
j                  d      r| j                  d|g|	dz   d	       |
j                  d
      s| j                  d|g|	dz   d       0 | j                  |      }t        |j!                         D cg c]  }|d   s	|d    c}      }|D ]7  }||v r|r||v r|j                  ||      }	| j                  d|||	dz          9 y c c}w )Nr6  c              3   B   K   | ]  \  }}g|d    k(  s|d     ywr8  rr   r:  s      r!   rT   z6MySQLDiff.find_unique_missing_in_db.<locals>.<genexpr>  r<  r=  rA   r>  r&   r?  r?   r@  rA  rB  rC  r9  rE  rM  s                  @r!   rW  z#MySQLDiff.find_unique_missing_in_db  s   "44Z@%d+ 	AEU]]i7||//:U]]"/"3"3GR"@"D"DX"N&+<&)  *baraxaxaz  *b  'bOm+*==j7)T
##$:J	S]`gSgh--:->%%i0''(=zG9V`cjVj  mC  D%%f-''(=zG9V`cjVjl  A%	A( 2248 /FWF^F^F`/pdefndo)/pq- 	jN!22^y8&99*nUJ 6
NT^ahThi	j 0qs   ?
G
Gr  rq   )r  r  r  r   r   r  r   r   r   r   r  r
  rj  rW  __classcell__r  s   @r!   r  r    s@     $!% O#
0
D'
-,,W\$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 ]9  }d}| j                  d|z  g       D ]  }|||d   f}|d    | j                  |<    ; y )Nr   zPRAGMA table_info('%s');r   notnullr  )r^   r   r	  r   r  s        r!   r   zSqliteSQLDiff.load_null  se    .. 	;J!J #../IJ/VXZ[ ;
!:z&/AB%/	%:!:		#;	;r#   c                      y rq   rr   r   s    r!   r   zSqliteSQLDiff.load_unsigned  r  r#   c                    |g }t        |      D cg c])  }|j                  s|j                  xs |j                  + }}|j	                         D ]<  }|d   }	t        |	      dk(  s|	d   }
|
|v s!|d   s|d   s,|j                  |
       > | j                  |      }t        |j	                         D cg c]  }|d   s	|d    c}      }|D ]  }||v s|j                  |        t        | )  |||||       y c c}w c c}w )Nr9  r   r   r6  ra  )rP  )r*   r6  r  r  rL  r   r.   r/  r   r  rW  )r^   r/   rN  rO  r   rP  r   rV  r.  r9  r   r+  rT  rU  r  s                 r!   rW  z'SqliteSQLDiff.find_unique_missing_in_db  s*   IHXY]H^oubgbnbn%//:U]]:oo+224 	-J +G7|q  ^+H1ETaIb$$V,	- 2248.FWF^F^F`/pdefndo)/pq- 	1N!22  0	1 	)$?PR\hq)r! p 0qs   DD:
D
D
c                      y rq   rr   r^   r/   rN  rO  r   s        r!   r_  z&SqliteSQLDiff.find_index_missing_in_db  r  r#   c                      y rq   rr   r  s        r!   rj  z)SqliteSQLDiff.find_index_missing_in_model  r  r#   c                     t         |   |||      }|sy |rJ| j                  |      }| j                  |      dk(  r%| j                  |      dk(  r|j	                  d      }|S )Nr  r?  r  )r  r
  r   r!  r  r  s         r!   r
  zSqliteSQLDiff.get_field_db_type  si    '+K
K2259J$$Z0F:t?T?TU\?]aj?j!../r#   rq   r  )r  r  r  r   r   r   r   rW  r_  rj  r
  r  r  s   @r!   r  r    s3     $!&;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                    |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               d|j                  d      d|j                  |d         d	S 
NrG   rH   r   rI   ALTERr   TYPErW   rX   r   r]   s       r!   ra   zPostgresqlSQLDiff.<lambda>  s
   UZUfUfgtUuw|  xG  xG  HJ  KO  PQ  KR  HS  xT  V[  Vg  Vg  ho  Vp  rw  rA  rA  BD  EI  JK  EL  BM  rN  PU  Pa  Pa  bh  Pi  kp  k|  k|  }A  BC  }D  kE  ;F r#   c                    |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               d|j                  d      d|j                  |d         d	S r  r   r]   s       r!   ra   zPostgresqlSQLDiff.<lambda>  s   Z_ZkZklyZz  }B  }L  }L  MO  PT  UV  PW  MX  }Y  [`  [l  [l  mt  [u  w|  wF  wF  GI  JN  OP  JQ  GR  wS  UZ  Uf  Uf  gm  Un  pu  pA  pA  BF  GH  BI  pJ  @K r#   c                    |j                  d      d|j                   ||d               d|j                  d      d|j                   ||d               d|j                  |d         d|j                  d      d	S )
NrG   rH   r   rI   zALTER COLUMNr   rW   r   rX   rc   r]   s       r!   ra   zPostgresqlSQLDiff.<lambda>  s
   RWRcRcdqRrty  uD  uD  EG  HL  MN  HO  EP  uQ  SX  Sd  Sd  es  St  v{  vE  vE  FH  IM  NO  IP  FQ  vR  TY  Te  Te  fj  kl  fm  Tn  pu  pA  pA  BL  pM  8N r#   c                 P    t         |           i | _        | j                          y rq   )r  r   check_constraintsload_constraintsr  s    r!   r   zPostgresqlSQLDiff.load	  s     !#r#   c                     | j                  | j                  g       D ]#  }|d   |d   |d   f}|d    | j                  |<   % y )Nnspnamerelnamer  
attnotnull)r   SQL_LOAD_NULLr   r^   r  r  s      r!   r   zPostgresqlSQLDiff.load_null  sQ    ##D$6$6; 	3Cy>3y>3y>BC!$\!22DIIcN	3r#   c                      y rq   rr   r   s    r!   r   zPostgresqlSQLDiff.load_unsigned  s     	r#   c                     | j                  | j                  g       D ]'  }|d   |d   |d   f}d|d   v s|| j                  |<   ) y )Nr  r  r  CHECKpg_get_constraintdef)r   SQL_LOAD_CONSTRAINTSr  r  s      r!   r  z"PostgresqlSQLDiff.load_constraints  sZ    ##D$=$=rB 	2Cy>3y>3y>BC#455.1&&s+	2r#   c                 8    dd | j                  |             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  s*    ?>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                  (     j                  d      S )NBooleanFieldr  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>)      $77>7R r#   i  c                  (     j                  d      S )NBinaryFieldr  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>*  s    $77=7Q r#   i  c                  (     j                  d      S Nr   r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>+      $77;7O r#   i  c                  (     j                  d      S Nr   r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>,  r  r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>-  r  r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>.  r  r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>/  r  r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>0  r  r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>1  r  r#   i  c                  (     j                  d      S )NBigIntegerFieldr  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>2  s    $77CT7U r#   i  c                  (     j                  d      S N
FloatFieldr  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>3      $77<7P r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>4  r  r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>5  r  r#   i[  c                  (     j                  d      S NDateTimeFieldr  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>6      $77?7S r#   i  c                  (     j                  d      S r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>7  r   r#   i  c                  (     j                  d      S )Nr   r  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>8  r  r#   c                  (     j                  d      S )NDurationFieldr  r  r   s   r!   ra   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>:  r   r#   z0django.contrib.postgres.search.SearchVectorFieldr  )i  i  i  rr   r   s   `r!   r   z1PostgresqlSQLDiff.get_data_types_reverse_override&  s    
+
R
 Q
 O	

 R
 R
 R
 O
 O
 O
 U
 P
 P
 P
 S
  S!
" R#
& TD<-
 	
r#   c           
         i }|j                  dd|g       |j                         D ]  \  }}}}||vr^g |j                         dk(  |j                         dv |j                         dk(  rt        |d   j	                  dd            nd	d
d
d||<   ||   d   j                  |        |j                  dd|g       |j                         D ],  \  }}||vrg d
d
d	dd
d||<   ||   d   j                  |       . |j                  d|g       |j                         D ]!  \  }	}
}}|	|vs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)r&  r6  zforeign keyr   r  r   NF)r9  ra  r6  rb  rd  rD  r9  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   r,  r.  r   kind	used_colsrD  r9  r6  primarys                r!   r  z!PostgresqlSQLDiff.get_constraints@  s     	  
#	% 4:??3D 	>/Ji,!#'::<=#@"jjl.GGHL

XeHe51););C)C#Dko""+J' 
#I.55f=	> 	  
#	% #)//"3 	>J,!#(##'!"+J' 
#I.55f=	> 	  \	 06/@ 		+E7FGK'#G}#*$#'"!&E"		 r#   c                 >   t         
|   |||      }|sy |r|j                  d      rY|j                  xs |j                  }| j                  d||f      d   d   }|j                  d      r|j                  dd      }|S |j                  rt        |t              r|dk(  rd}n|d	k(  rd
}|r|j                  }|dk(  rd}|j                  xs |j                  }| j                  j                  |||fi       j                  dd       }|r|j                  dd      }|j                  dd      }dj                  |j                  d      D 	cg c]4  }	d|	v xr( dj                  d |	j                  dd      D              xs |	6 c}	      }|d|z   z  }|S c c}	w )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 varyingr?  r  serialbigint	bigserialr  r   r  z((r  z))rj   z("z" c              3   >   K   | ]  }|j                  d         yw)"N)r  )rQ   ps     r!   rT   z6PostgresqlSQLDiff.get_field_db_type.<locals>.<genexpr>  s     HoZ[QTHos   rH   r   )r  r
  endswithr  r  r   rK  r  ra  r   r   r   r  r  r[   r  )r^   r   r   r   r-   r  introspect_db_typer	  check_constraintrt   r  s             r!   r
  z#PostgresqlSQLDiff.get_field_db_type  s   '+K
K%  //:U]]%)%5%5  )
& 
& 
&" &001DE);)C)CDWYb)c&))  Zy%Ai'&G()G"00
#!)J//:U]]#'#9#9#=#=z:W^>_ac#d#h#hi  BF  $G #'7'?'?c'J$'7'?'?c'J$'+yy  O  U  U  VY  Z  2[yz#(2otyyHo_`_f_fgjlm_nHo?o2tst2t  2[  (\$s%555G 2[s   9Fc                     	 | j                  d|g      d   d   }| j                  j                  |j                  d            S # t        t
        f$ r Y y 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  s`    	##$SV_U`abcdenoD//33DJJsODDH% 		s   AA AAr  )r  r  r  r   r   r7  r  r  r   r   r   r   r   r   r  r  r   r  r
  r   r  r  s   @r!   r  r    s~     $!% ?;M F "K N 
3

2

4Yf.`r#   r  )postgispostgresql_psycopg2
postgresqlmysqlsqlite3oraclec                   T     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         |   |       |j                  dd       |j                  dddddd	
       |j                  dddddd
       |j                  dddddd       |j                  dddddd       |j                  ddddd       |j                  ddddd       |j                  d dd!dt        j                         y )"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  rF  rE  rG  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-defaultsrp  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!   rJ  zCommand.add_arguments  s"   f%Ks3 $|#K	 	 	
 	!4 r	 	 	
 	d<ne 	 	

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

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

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

 	!,=P"" 	 	
r#   c                 2    t        |   |i | d| _        y )Nr   )r  r   	exit_code)r^   r`   r   r  s      r!   r   zCommand.__init__1  s    $)&)r#   c                 v   ddl m} |d   }d }t        |d      r|j                  d   d   }n|j                  }|dk(  rt        d      |d	   rt        j                  d
      }nj|st        d      t        |t        t        t        f      s|g}g }|D ]8  }t        j                  |      }|j                  |j                  d
             : |st        d      |d   }	|	rddlm}
  |
dg|d
d
d |s"t         j"                  j%                  d      d   }d|v r|j%                  d      d   }t&        j)                  |t*              } |||| j,                  | j.                        }|j1                          |j3                          |j4                  sd| _        |j9                  | j:                         y )Nr   )settingsr   	DATABASESrE  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.rI  )call_commandmigrate)no_input
run_syncdbr  r   )r   r   )django.confrR  r  rS  DATABASE_ENGINEr	   r   
get_modelsr   r   r   r   get_app_configr)   django.core.managementrW  r   r  r  DATABASE_SQLDIFF_CLASSESr  r  r   r   r   r  r   rP  r  rS   )r^   r`   r   rR  
app_labelsenginer   r   
app_configrI  rW  clssqldiff_instances                r!   handlezCommand.handle5  s   ([)
8[)''	28<F--FW   a b b %&dCJ"#@AAj4*<=(\
J' T	!00;
!!*"7"7T"7"RST LMM#$78;PZP$4P**005b9F&=\\#&r*F&**6>Bz74;;t{{[))+//DN##DJJ/r#   c                 V   	 t        |   |i | y # t        $ r}|d   r t        | dd       }|s.t	        t
        j                  | j                  j                        }|j                  |j                  j                  d|       t        j                  d       Y d }~y d }~ww xY w)N	tracebackr   z: rW   )r  r   r	   r   r
   sysr   rS   r   r  r  r  exit)r^   r`   r   rt   r   r  s        r!   r   zCommand.executek  s    	GOT-W- 		{# T8T2F&szz4::3C3CDLLQ[[%9%91=>HHQKK		s    	B(BB##B(c                 b    t         |   |       t        j                  | j                         y rq   )r  run_from_argvrj  rk  rP  )r^   argvr  s     r!   rm  zCommand.run_from_argvy  s     d# r#   )r  r  r  rG  output_transactionrJ  r   r   rg  r   rm  r  r  s   @r!   r@  r@    sB    ND '
R 30 30j! !r#   r@  )+__doc__r  rj  rL  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  ra  r@  rr   r#   r!   <module>rz     s   ,  
  2 2  < 5 1 5 5 - ; 7 <hT2 u  w
< w
<tW ]j ]j@;G ;|F FT !,# }!k }!r#   