
    kh                       U 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 d<   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)nullORDERING_FIELDc                 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       d/var/www/histauto/venv/lib/python3.11/site-packages/django_extensions/management/commands/sqldiff.pyflattenr#   *   s    IIE
s))C	A
c#hh,,Q(( 	(q6 (


Q!$QAAI 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;Z1	 dEd<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   sd       
 
1 %&FFEa   0A0A!0D0D
 
 
 
 
 
r$      ;)rP   	SQL_TABLE	SQL_FIELDjoin	enumerateselfrT   qnargss    `  r"   <lambda>zSQLDiff.<lambda>r   s    -((((47$$$$,''''47$$$$ 
 
 
 
!$qrr(++
 
 
 	
 	
 	
 	
	= r$   c                     |                     d          d|                     ||d                             d|                     d          d|                     ||d                             dS )NrH   rI   r   rJ   zDROP COLUMNr   rW   rP   rX   rY   r\   s       r"   r`   zSQLDiff.<lambda>|   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 )NrH   rI   r   rJ   rK   r   c              3   ~   K   | ]7\  }}|d k    r                     |          n                    |          V  8dS rM   rN   rQ   s      r"   rU   z#SQLDiff.<lambda>.<locals>.<genexpr>   sd        Aq )*Q!!!$$$E4E4Ea4H4H     r$      
REFERENCESrV    (   )rW   )rP   rX   rY   rZ   r[   r   opsdeferrable_sqlr\   s    `  r"   r`   zSQLDiff.<lambda>   s=   m,,,,OOBBtAwKK((((l++++OOBBtAwKK((((HH    %d122h//       l++++OOBBtAwKK((((OOBBtAwKK((((N))++++'
 r$   c                    |                     d          d|                     |d                             d|                     d          d|                     |d                             d|                    d                    fd	|d
         D                                 |                     |d                   dS )NzCREATE INDEXrI   rV   rJ   ONr   rg   , c              3   .   K   | ]} |          V  d S N rR   er^   s     r"   rU   z#SQLDiff.<lambda>.<locals>.<genexpr>   s+      !9!9A""Q%%!9!9!9!9!9!9r$   r   rh   );rP   rX   rY   rZ   r\   s     ` r"   r`   zSQLDiff.<lambda>   s    .))))47$$$$$47$$$$		!9!9!9!9a!9!9!999:::$q'""""= r$   c                 |    |                     d          d|                     ||d                             dS )Nz
DROP INDEXrI   r   rW   rP   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 )NrH   rI   r   rJ   zADD CONSTRAINTrV   UNIQUErg   rn   c              3   .   K   | ]} |          V  d S rp   rq   rr   s     r"   rU   z#SQLDiff.<lambda>.<locals>.<genexpr>   s+      %=%=bbee%=%=%=%=%=%=r$   r   rt   ru   r\   s     ` r"   r`   zSQLDiff.<lambda>   s    m,,,,OOBBtAwKK((((.////OOBBtAwKK((((h''''OODII%=%=%=%=T!W%=%=%===>>>>'
 r$   c                    |                     d          d|                     ||d                             d|                     d          d|                     d          d|                     ||d                             d
S )	NrH   rI   r   rJ   DROP
CONSTRAINTr   rW   rw   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 	NrH   rI   r   rJ   MODIFYr   rV   rW   rP   rX   rY   rO   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 )
NrH   rI   r   rJ   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T!W---/ / r$   c                 d    |                     d|                    |d                   z            S )Nz-- Comment: %sr   )r   rX   r\   s       r"   r`   zSQLDiff.<lambda>   s,    5??473331 1 r$   c                 >    |                     d|d         z            S )Nz-- Table missing: %sr   r   r\   s       r"   r`   zSQLDiff.<lambda>   s     ELLa(= = r$   c                 >    |                     d|d         z            S )Nz-- Model missing for table: %sr   r   r\   s       r"   r`   zSQLDiff.<lambda>   s"    u||(472@ @ 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_outputr8   )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)rR   
table_infos     r"   
<listcomp>z SQLDiff.load.<locals>.<listcomp>  s*     
 
 
 O
 
 
r$   )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B,7 C 
 

 
"0??LL
 
 

 ) 	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    !:
 
 	
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    !;
 
 	
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   )rR   r   s     r"   r   z'SQLDiff.sql_to_dict.<locals>.<listcomp>4  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_kwargsA  s	     	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   r:   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'   publicrI   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_typeK  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++%I*1~~~yyy:  
  44
  
   L!! 	*'<>>LlD)) 	0MM,x0111'/L  {D11W<<KLlE** 	+MM,q/***'?L;&&;q>&#.q>F< >))#.q>F< A63{1~#6#6H+a. #$ q> 	&"F7O#===!%v 	'WUK77 	'"&F;?**!!nG (,'9'K'KG( ($L*  *j)))ClRL44K
L
 
 	l###**<88#--f--555LL(
 	"!JL
 ]	   $3=HH'4}}d6J6JKMs   A A6CCc                     d S rp   rq   )r]   r  s     r"   r   z SQLDiff.get_field_db_type_lookup  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_class  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_nullable  sE    (
!J/2U]y}}j*g>HHHr$   c                     |rL|dk    rF|                     d          d                              d          d                                         S |S )Nzdouble precisionrI   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                     g }t          |d          r$|t          t          |j                            z  }|j        D ]}|                    |j                   |                     ||          S )Nindex_together)hasattrr   r   r%  indexesr/   fieldsexpand_together)r]   r0   indexes_normalizedidxs       r"   get_index_togetherzSQLDiff.get_index_together  s|    4)** 	P$'9$:M'N'N"O"OO< 	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]   r0   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  )rR   r   r0   s     r"   rU   z*SQLDiff.expand_together.<locals>.<genexpr>  s2      HHdnnU++3HHHHHHr$   )r   r/   r   )r]   togetherr0   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 columnsr9  Nrq   rR   contraint_namer1  r  s      r"   rU   z4SQLDiff.find_unique_missing_in_db.<locals>.<genexpr>  J       * *6NJ#9
9(=== #8,====* *r$   rB   _uniqr'   varcharr@   _like varchar_pattern_opstext text_pattern_opsc                 >    g | ]}|d          
|d         |d         S )r9  indexr<  rq   rR   vs     r"   r   z5SQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  sD       X; ()z)  r$   r   SchemaEditorClassr+   r  r9  managedr  r  anyitems_create_index_namer   r.   
startswithr2  r   valuesr]   r0   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++ $	 $	E U]i77| ! !/:U]"/"3"3GR"@"@"D"DX"N"N& +< &) * * * *:K:Q:Q:S:S* * * ' 'O
 m+++*==j7)TT
##*J	:PWCW    --:->>%%i00 ''-" 	"W,.   %%f-- ''-" 	"W,+   22488. *1133  
 
 . 	 	N!222 ^y88&99*nUUJ&
NJQXDX   	 	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  rR   r   s     r"   r   z8SQLDiff.find_unique_missing_in_model.<locals>.<listcomp>      QQQe,QQQr$   r9  rG  r<  r   r   rC   )	r   r+   r2  rN  r   r  r9  r   r   )r]   r0   rS  rT  r   r(  r.  constraint_namer1  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'   rA  rB  rC  rD  rE  c                 >    g | ]}|d          
|d         |d         S )rG  r9  r<  rq   rH  s     r"   r   z4SQLDiff.find_index_missing_in_db.<locals>.<listcomp>U  sD       W: '(k)  r$   _idx)r   rK  r+   db_indexr  r  rO  r   r.   rP  r,  r   rQ  r'  r   r(  )r]   r0   rS  rT  r   rV  r   r  rX  r.   r%  db_index_togetherr<  rG  s                 r"   find_index_missing_in_dbz SQLDiff.find_index_missing_in_db5  s/    #4Z@@%d++ 	 	E~ /:U]-//!.!A!A*wi!X!XJ''-zG9jRT   $mmzmBBG)))44 ++1&$I&02   ))&11 ++1&$I&0/   0066. *1133  
 
 & 	 	G+++&99*gNNJ%z7J<OQS    \ 	 	Ez!222##):u|UZQS  	 	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>l  r`  r$   c                     g | ]	}|j         
S rq   r   rR   r+  s     r"   r   z7SQLDiff.find_index_missing_in_model.<locals>.<listcomp>m      ===CH===r$   r9  rG  r<  r   r   primary_keyforeign_keyr   r+  orderscheckr'   spatial_indexFrA   )r   r+   r'  r,  rN  r  r   rn  r   r   
ForeignKeydb_constraintr9  rf  db_checkr   r   r   r   )r]   r0   rS  rT  r   r(  meta_index_namesr%  ra  r1  r<  r   s               r"   find_index_missing_in_modelz#SQLDiff.find_index_missing_in_modeli  s;    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 }-"5&*;<< +
 h' EL w'
"6*e33"x00 4 4 g& 5> g& 5>>Z>+P+P 5/599  g& 5>>^+K+K 8*oVVVVY,	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   rR   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   )rN  remote_fieldr*   modelr,   db_tabler5  
field_namer  r/   r.   r   r   has_defaultget_prep_valueget_defaultr   r   r   add)	r]   ry  rz  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**!% / ''!.4:C!.4:DD % 2 = $	   .BB.B##EMMZM$H$HIII< 23 8I8I8K8K  ''$u';';E<M<M<O<O'P'PP   z 4 ''
333##B
JNNNNN"&&
J'?@@@1	A 	Ar$   c                    t          d |D                       }t          |          D ]}|j        |vr||j                 }|                     |          }|                     |||          }	|r |||||	          \  }}	|                     |	          |                     |          k    s$|	|fdvr|                     d||j        ||	           d S )Nc                 "    g | ]}|d          |fS r   rq   r~  s     r"   r   z2SQLDiff.find_field_type_differ.<locals>.<listcomp>       EEEC3q63-EEEr$   >   serialinteger	bigserialbigintrD   )r   r+   r   r   r  r#  r   )
r]   r0   rz  r   funcr  r   r   
model_typer.   s
             r"   find_field_type_differzSQLDiff.find_field_type_differ  s   EE3DEEEFF	%d++ 	 	Ez**#EJ/K22599J,,[%LLG  T&*d5+z7&S&S#
G((11T5J5J6 6  J' 0   ##'UZW  %	 	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>  r  r$   r'   rq  z CHECKr   r  ri   rE   )r   r+   r   r   r  r#  db_parametersr   r   striplstriprstripr   )r]   r0   rz  r   r  r  r   r   r  r.   model_checkru  s               r"   find_field_parameter_differz#SQLDiff.find_field_parameter_differ  s    EE3DEEEFF	%d++ 	 	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  /	 	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|   SETrF   )r   r+   r  r  r   r  r   r   )r]   r0   rz  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_constraints  s    	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>0  s@        _;(9(9(;(;UC  r$   r   r9   zunable to introspect table: %sr<  r   rn  r9  r   )rn  r9  r   r>  r   c                 4    g | ]\  }}}t          |          S rq   )r   )rR   
_app_label_model_namediffss       r"   r   z,SQLDiff.find_differences.<locals>.<listcomp>q  s%    OOO:JUSZZOOOr$   ))r   r   r   r   IGNORE_MISSING_TABLESr   r   r,   r  r   r(   __name__r&  r   r  r   r   r+   order_with_respect_tor   get_table_description	Exceptionstrr  r   rollbackrN  r   r  rb  rw  r{  r  r[  rh  r  r  r  maxr   r   )r]   tablecur_app_label	app_modelr0   r   r   rT  ry  rz  rs   rS  r>  dctr<  s                  r"   find_differenceszSQLDiff.find_differences
  s   <*+ 	I%%dD111 I I!333T%???''(@%HHH Z	P Z	PI?DJI< 67 DJ 	)))))Y5GHHH//##$9:FFFt)+<== $($6$F$FK% %!! %)$8$8KT-?% %!  !1$!7!7   H ) 4%3"	$($6$L$LK% %!!    ##=AN   $&&& M'8'>'>'@'@  #i.w<<1$$'*='9"%h- #*8	1 1M'!*- --m%6
   ,,m%6
   ,,X7H*UUU ))(4EzRRR**m%6
   ))m%6
   ''.?LLL,,T3DjQQQ**41BJOOOO"OOd>NOOO 
  
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]   rT   s     r"   
print_diffzSQLDiff.print_difft  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:rI   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   rR   r!   rs   rT   s      r"   rU   z*SQLDiff.print_diff_text.<locals>.<genexpr>  s}       9 9 1 A,6q4-,H,HODIIaLLLa 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"   rU   z*SQLDiff.print_diff_text.<locals>.<genexpr>  sW          1 EQJ15;;q>>6Q           r$   z|--+AppModel)r   r   writer   r   r   r   rX   
DIFF_TEXTSr   r[   rZ   r   )
r]   rT   r  r   r   r  diffr   	diff_argsrD  s
    `        r"   r  zSQLDiff.print_diff_text{  s9   - 	"K'    Kb!!!. 	"K'    Kb!!!,0,< /	0 /	0(Iz5 : *) *0J0J!!||$45555uy7Q7Q7QS   !*: * !! %ABBBB
333    0 0'+$	9y1D 9 9 9 9 !*) 4 49 9 9 5 5  xx         )$**S// : :        z 0K%%f1E1E1E1Ett&LMMMM  0)) !&U 3 3 3 3 %	 : : : : %W 5 5 5 5 %
 ; ; ; ; $	 	 	 	 ))$////=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: %srJ   rI   zCOMMIT;)r   r   r  r   r   rj   
quote_namer   r   rP   r   rX   r   replace)r]   rT   r  r^   r   r   r  r  r   r  rD  s              r"   r  zSQLDiff.print_diff_sql  s8   - 	"K'    Kb!!!^&# 	<: J!!%"3"34G"H"HIIIIIJ J Ke//99:::040@ , ,,	:u z .my&@&@K%%%9EOOI<V<V%VWW   %.Mz j K%%^eooj6Q6Q%QRR   " , ,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,  r2  r)  r[  rb  rh  rw  r{  r  r  r  r  r  r  r   r  r  r  rq   r$   r"   r6   r6   H   s       "$ 	  J$  #B"CW"Zb!ek"g m#iX"^[ J$	 	" "	
 	
 " " "
	
 	
 # # " "  I K " " !&!&O 
  
  
D! ! !"
 
 

 
 
= = =; ; ;0 0 0    (4 4 4    Z Z Z Zx  + + +I I I  

> 
> 
>= = =   MQ> > > >@X X X42 2 2h3W 3W 3WjR R R
A A A8   2 9=! ! ! !FS S S  h
 h
 h
T  (xzz ( ( ( (C0 C0 C0J#< #< #< #< #<r$   r6   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!  )rR   r3   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%%+
  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 % ' '
!: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_increment  s}    . 	- 	-J%%3  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charrA  varboolr  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_type/  s    ''++K
KK 	F 	-22599J %%j11V;;))'22i??!..// $$Z00F::i''$G  $% % *:)H)H,,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>N  r`  r$   c                     g | ]	}|j         
S rq   r   rl  s     r"   r   z9MySQLDiff.find_index_missing_in_model.<locals>.<listcomp>O  rm  r$   r9  rG  r<  r   r   rA   rn  ro  r   r+  rp  rq  r'   rr  F)r   r+   r'  r,  r2  rN  r  r   r   rn  r   r   rs  rt  r9  rf  ru  r   r   r   )r]   r0   rS  rT  r   r(  rv  r%  r.  ra  r1  r<  r   s                r"   rw  z%MySQLDiff.find_index_missing_in_modelK  s    QQ:J4:P:PQQQRR=====006622488+<+B+B+D+D 7	W 7	W'OZ"222(# Jw,?  +GJJwqz**E 7||q   ''0*o   m, 1B }-"5&*;<< +
 h' EL w'
"6*e33"x00 4 4 g& 5> g& 5>>Z>+P+P 5/599  g& 5>>^+K+Kw'"8, g/99 8*oVVVVo7	W 7	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 )Nr9  c              3   H   K   | ]\  }}g|d          k    |d         V  dS r;  rq   r=  s      r"   rU   z6MySQLDiff.find_unique_missing_in_db.<locals>.<genexpr>  r?  r$   rB   r@  r'   rA  r@   rB  rC  rD  rE  c                 .    g | ]}|d          
|d         S r9  r<  rq   rH  s     r"   r   z7MySQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  %    MMMa8MQy\MMMr$   rJ  rR  s                 @r"   r[  z#MySQLDiff.find_unique_missing_in_db  s    #4Z@@%d++ $	 $	E U]i77| ! !/:U]"/"3"3GR"@"@"D"DX"N"N& +< &) * * * *:K:Q:Q:S:S* * * ' 'O
 m+++*==j7)TT
##*J	:PWCW    --:->>%%i00 ''-" 	"W,.   %%f-- ''-" 	"W,+   22488 /MM#4#;#;#=#=MMM
 
 . 
	 
	N!222 ^y88&99*nUUJ&
NJQXDX   
	 
	r$   r  rp   )r  r  r  r   r   r  r   r   r   r   r  r  rw  r[  __classcell__r  s   @r"   r  r    s         $!% O# # # # #
0 0 0D D D' ' ' - - -$     8?W ?W ?WD MQ; ; ; ; ; ; ; ;r$   r  c                   N     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  sz    . 		; 		;J!J #..*Z7  ; ;
 ":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   )r9  r  r  r_  s     r"   r   z;SqliteSQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  s9     
 
 
|
O,u}
 
 
r$   r<  r   r   r9  rn  c                 .    g | ]}|d          
|d         S r  rq   rH  s     r"   r   z;SqliteSQLDiff.find_unique_missing_in_db.<locals>.<listcomp>  r  r$   )rU  )r+   rQ  r   r/   r2  r   r  r[  )r]   r0   rS  rT  r   rU  rZ  r1  r<  r  r.  rY  r  s               r"   r[  z'SqliteSQLDiff.find_unique_missing_in_db  s]    I
 
)$//
 
 
 ,2244 	- 	-J +G7||q   ^++x( ,,6},E , $$V,,,22488.MM#4#;#;#=#=MMM
 
 . 	1 	1N!222  000))-!2J) 	* 	
 	
 	
 	
 	
r$   c                     d S rp   rq   r]   r0   rS  rT  r   s        r"   rh  z&SqliteSQLDiff.find_index_missing_in_db  	     	r$   c                     d S rp   rq   r  s        r"   rw  z)SqliteSQLDiff.find_index_missing_in_model	  r  r$   c                    t                                          |||          }|sd S |r\|                     |          }|                     |          dk    r.|                     |          dk    r|                    d          }|S )Nr  rA  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 %%j11V;;))'22i??!..//r$   rp   r  )r  r  r  r   r   r   r   r[  rh  rw  r  r  r  s   @r"   r  r    s         $!&
; 
; 
;   MQ 
  
  
  
  
  
H  
  
         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 
NrH   rI   r   rJ   ALTERr   TYPErV   rW   r   r\   s       r"   r`   zPostgresqlSQLDiff.<lambda>7  s    -((((47$$$$'""""47$$$$&!!!!$q'""""; 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    m,,,,OOBBtAwKK((((g&&&&OOBBtAwKK((((f%%%%d1g&&&&'
 r$   c                 V   |                     d          d|                     ||d                             d|                     d          d|                     ||d                             d|                     |d                   d|                     d          d	S )
NrH   rI   r   rJ   zALTER COLUMNr   rV   r   rW   rb   r\   s       r"   r`   zPostgresqlSQLDiff.<lambda>J  s    -((((47$$$$.))))47$$$$$q'""""*%%%%8 r$   c                 ~    t                                                       i | _        |                                  d S rp   )r  r   check_constraintsload_constraintsr  s    r"   r   zPostgresqlSQLDiff.loadS  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_nullX  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]  r  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_constraintsb  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_arrayfieldh  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>s      $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>t  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>u      $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>v  r(  r$   i  c                  0                          d          S r/  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>w  r(  r$   i  c                  0                          d          S r/  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>x  r(  r$   i  c                  0                          d          S r,  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>y  r-  r$   i  c                  0                          d          S r,  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>z  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 )NBigIntegerFieldr&  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>|  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>}      $77<7PP r$   i  c                  0                          d          S r8  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>~  r:  r$   i  c                  0                          d          S r8  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>  r:  r$   i[  c                  0                          d          S NDateTimeFieldr&  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>      $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>  r@  r$   i  c                  0                          d          S )Nr   r&  r'  r   s   r"   r`   zCPostgresqlSQLDiff.get_data_types_reverse_override.<locals>.<lambda>  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_overridep  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)rF  r9  zforeign keyr   r  r   NF)r<  rn  r9  ro  rq  rG  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   r/  r1  r  kind	used_colsrG  r<  r9  primarys                r"   r  z!PostgresqlSQLDiff.get_constraints  s     	 z"!	
 	
 	
$ 4:??3D3D 	> 	>/Ji,,!#'::<<=#@"jjll.GGzz||}44 $)1););C)C)C#D#D#D""	+ 	+J' 
#I.55f==== z"	
 	
 	
 #)//"3"3 	> 	>J,,!#(##'!"+ +J' 
#I.55f==== L!	
 	
 	
$ 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 varyingrA  r  r  r  r  r  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  )rR   ps     r"   rU   zAPostgresqlSQLDiff.get_field_db_type.<locals>.<listcomp>.<genexpr>C  s,      )P)P1!''#,,)P)P)P)P)P)Pr$   rI   r   )rZ   r   )rR   rs   s     r"   r   z7PostgresqlSQLDiff.get_field_db_type.<locals>.<listcomp>A  sf        !"  1H Q $		)P)PQ)P)P)P P P!   r$   rI   )r  r  endswithr  r  r   rP  r  rn  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 8	6%% *  /:U]%)%5%5  )
& 
& 
& 
&" &001DEE );)C)C+Y* *& *)  *Zy%A%A * i''&GG(()G 6"0
##!)J/:U]#'#9#=#=W5r$ $#,d33 ! $ 6'7'?'?c'J'J$'7'?'?c'J'J$'+yy  &6%;%;C%@%@	  ( ($ 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_lookupL  s}    	##?) D /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 	
 	
           
3 3 3
  
2 2 2
 
 

 
 
4d d d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_argumentss  s   f%%%Ks333 #K 	 	
 	
 	
 	!  5 	 
	
 
	
 
	
 	C 	 
	
 
	
 
	
 	 M 	 	
 	
 	
 	$'4 	 	
 	
 	
 	 #F 	 	
 	
 	
 	!$" 	 	
 	
 	
 	
 	
r$   c                 H     t                      j        |i | d| _        d S )Nr   )r  r   	exit_code)r]   r_   r   r  s      r"   r   zCommand.__init__  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  rT   )r]   r_   r   rp  
app_labelsenginer   r   
app_configrg  ru  clssqldiff_instances                r"   handlezCommand.handle  sP   (((((([)
8[)) 	.'	28<FF-FW +   %& 	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3DK
 
 
 	))+++/ 	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   rT   r   r  r  r  exit)r]   r_   r   rs   r   r  s        r"   r   zCommand.execute  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_argv   s3    d###     r$   )r  r  r  re  output_transactionrh  r   r   r  r   r  r  r  s   @r"   r^  r^  i  s        ND =
 =
 =
 =
 =
~     90 90 ]90v    ! ! ! ! ! ! ! ! !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   __annotations__r   r   r#   r+   r6   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 < < < < < <+|H4@@@ @ @ @ u       [< [< [< [< [< [< [< [<|    W   V V V V V V V VrP P P P PG P P Pf       F
 !,#  Y! Y! Y! Y! Y!k Y! Y! Y! Y! Y!r$   