
 X                 @   s   d  d l  Z  d  d l Z d  d l m Z d  d l m Z d  d l m Z d  d l m Z m	 Z	 d  d l
 m Z e j d  Z d d	   Z Gd
 d   d e  Z d S)    N)datetime)truncate_name)atomic)sixtimezone)force_byteszdjango.db.backends.schemac             C   s9   t  d d   |  j j j D d d   | j j j D  S)Nc             s   s!   |  ] } | j  j s | Vq d  S)N)fieldmany_to_many).0obj r   L/home/ubuntu/projects/ifolica/build/django/django/db/backends/base/schema.py	<genexpr>   s    z+_related_non_m2m_objects.<locals>.<genexpr>c             s   s!   |  ] } | j  j s | Vq d  S)N)r   r	   )r
   r   r   r   r   r      s    )zipmodel_metarelated_objects)	old_field	new_fieldr   r   r   _related_non_m2m_objects   s    r   c               @   sk  e  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 d d d d  Z d d   Z d d   Z g  d  d!  Z  d" d#   Z! e" d$ d%    Z# d d& d'  Z$ d( d)   Z% d* d+   Z& d, d-   Z' d. d/   Z( d0 d1   Z) d2 d3   Z* d4 d5   Z+ d6 d7   Z, d8 d9   Z- d: d;   Z. d< d=   Z/ d> d?   Z0 d@ dA   Z1 d dB dC  Z2 d dD dE  Z3 dF dG   Z4 dH dI   Z5 dJ dK dL  Z6 dJ d dM dN  Z7 dO dP   Z8 dQ dR   Z9 dS dT   Z: dU dV   Z; dW dX   Z< dY dZ   Z= d d d d d d d[ d\  Z> d S)]BaseDatabaseSchemaEditoraW  
    This class (and its subclasses) are responsible for emitting schema-changing
    statements to the databases - model creation/removal/alteration, field
    renaming, index fiddling, and so on.

    It is intended to eventually completely replace DatabaseCreation.

    This class should be used by creating an instance for each set of schema
    changes (e.g. a migration file), and by first calling start(),
    then the relevant actions, and then commit(). This is necessary to allow
    things like circular foreign key references - FKs will only be created once
    commit() is called.
    z'CREATE TABLE %(table)s (%(definition)s)z1ALTER TABLE %(old_table)s RENAME TO %(new_table)sz7ALTER TABLE %(table)s SET TABLESPACE %(new_tablespace)szDROP TABLE %(table)s CASCADEz:ALTER TABLE %(table)s ADD COLUMN %(column)s %(definition)sz!ALTER TABLE %(table)s %(changes)sz%ALTER COLUMN %(column)s TYPE %(type)sz%ALTER COLUMN %(column)s DROP NOT NULLz$ALTER COLUMN %(column)s SET NOT NULLz/ALTER COLUMN %(column)s SET DEFAULT %(default)sz$ALTER COLUMN %(column)s DROP DEFAULTz4ALTER TABLE %(table)s DROP COLUMN %(column)s CASCADEzDALTER TABLE %(table)s RENAME COLUMN %(old_column)s TO %(new_column)szFUPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULLz?ALTER TABLE %(table)s ADD CONSTRAINT %(name)s CHECK (%(check)s)z.ALTER TABLE %(table)s DROP CONSTRAINT %(name)szBALTER TABLE %(table)s ADD CONSTRAINT %(name)s UNIQUE (%(columns)s)z|ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) REFERENCES %(to_table)s (%(to_column)s)%(deferrable)sNz9CREATE INDEX %(name)s ON %(table)s (%(columns)s)%(extra)szDROP INDEX %(name)szGALTER TABLE %(table)s ADD CONSTRAINT %(name)s PRIMARY KEY (%(columns)s)FTc             C   sC   | |  _  | |  _ |  j r' g  |  _ n  |  j  j j o9 | |  _ d  S)N)
connectioncollect_sqlcollected_sqlfeaturesZcan_rollback_ddlatomic_migration)selfr   r   r   r   r   r   __init__I   s
    			z!BaseDatabaseSchemaEditor.__init__c             C   s;   g  |  _  |  j r7 t |  j j  |  _ |  j j   n  |  S)N)deferred_sqlr   r   r   alias	__enter__)r   r   r   r   r    R   s
    		z"BaseDatabaseSchemaEditor.__enter__c             C   sV   | d  k r0 x! |  j  D] } |  j |  q Wn  |  j rR |  j j | | |  n  d  S)N)r   executer   r   __exit__)r   exc_type	exc_value	tracebacksqlr   r   r   r"   Y   s
    	z!BaseDatabaseSchemaEditor.__exit__c          
   C   s   t  j d | | d i | d 6| d 6|  j r | j d  rE d n d } | d k	 r |  j j | t t |  j |   |  q |  j j | |  n( |  j	 j
    } | j | |  Wd QXd S)zM
        Executes the given SQL statement, with optional parameters.
        z%s; (params %r)extraparamsr&   ; N)loggerdebugr   endswithr   appendtuplemapquote_valuer   cursorr!   )r   r&   r(   Zendingr2   r   r   r   r!   b   s    '	-z BaseDatabaseSchemaEditor.executec             C   s   |  j  j j |  S)N)r   ops
quote_name)r   namer   r   r   r4   r   s    z#BaseDatabaseSchemaEditor.quote_namec             G   sD   t  j   } x! | D] } | j t |   q W| j   d d  S)zx
        Generates a 32-bit digest of a set of arguments that can be used to
        shorten identifying names.
        N   )hashlibmd5updater   	hexdigest)clsargshargr   r   r   _digestu   s    z BaseDatabaseSchemaEditor._digestc       
      C   s  | j  d |  j  } | d } g  } | d k r5 d S| j } | oQ |  j |  } | r |  j |  } | d k	 r |  j j j r | d |  j |  7} q | d 7} | | g 7} q n  | j r | j	 r |  j j j
 r d } n  | r	|  j j j r	| d 7} n | s| d 7} n  | j	 r2| d 7} n | j rH| d	 7} n  | j pZ| j j }	 |	 r|  j j j r| j r| d
 |  j j j |	 d d 7} n  | | f S)z
        Takes a field and returns its column definition.
        The field must already have had set_attributes_from_name called.
        r   typeNz DEFAULT %sTz NULLz	 NOT NULLz PRIMARY KEYz UNIQUEz %sinline)NN)db_parametersr   nullskip_defaulteffective_defaultr   requires_literal_defaultsprepare_defaultempty_strings_allowedprimary_key!interprets_empty_strings_as_nullsZimplied_column_nulluniquedb_tablespacer   Zsupports_tablespacesr3   tablespace_sql)
r   r   r   include_default	db_paramsr&   r(   rC   default_valueZ
tablespacer   r   r   
column_sql   s:    
	
			&z#BaseDatabaseSchemaEditor.column_sqlc             C   s   d S)z
        Some backends don't accept default values for certain columns types
        (i.e. MySQL longtext and longblob).
        Fr   )r   r   r   r   r   rD      s    z%BaseDatabaseSchemaEditor.skip_defaultc             C   s   t  d   d S)zU
        Only used for backends which have requires_literal_defaults feature
        zsubclasses of BaseDatabaseSchemaEditor for backends which have requires_literal_defaults must provide a prepare_default() methodN)NotImplementedError)r   valuer   r   r   rG      s    z(BaseDatabaseSchemaEditor.prepare_defaultc             C   s%  | j    r | j   } n | j rg | j rg | j rg | j   d k rX t j   } q t j   } n t	 | d d  s t	 | d d  r t
 j   } | j   } | d k r | j } q | d k r | j } q | d k r t j } q n d } t |  r|   } n  | j | |  j  } | S)	zD
        Returns a field's effective database default value
        ZBinaryFieldZauto_nowFZauto_now_addZ	DateFieldZ	TimeFieldZDateTimeFieldN)has_defaultZget_defaultrC   ZblankrH   get_internal_typer   binary_type	text_typegetattrr   nowdatetimer   callableZget_db_prep_saver   )r   r   defaultZinternal_typer   r   r   rE      s(    $z*BaseDatabaseSchemaEditor.effective_defaultc             C   s   t     d S)aY  
        Returns a quoted version of the value so it's safe to use in an SQL
        string. This is not safe against injection from user code; it is
        intended only for use in making SQL scripts or preparing default values
        for particularly tricky backends (defaults are not user-defined, though,
        so this is safe).
        N)rR   )r   rS   r   r   r   r1      s    z$BaseDatabaseSchemaEditor.quote_valuec                s  g  } g  } x  j  j D]} |  j   |  \ } } | d k rI q n  | j d |  j  } | d r} | d | d 7} n  | j d |  j  } | r | d | 7} n  | j |  | j rp| j rp| j j	 j  j
 }	 | j j	 j  j | j j  j }
 |  j j j r,|  j j |  j   | d   qp|  j rp| d |  j i |  j |	  d 6|  j |
  d	 67} qpn  | j d
 |  j | j  | f  | j   d k r |  j j j   j  j
 | j  } | r|  j j |  qq q WxI   j  j D]; }   f d d   | D } |  j j |  j   |   qW|  j i |  j   j  j
  d 6d j |  d 6}   j  j r|  j j j   j  j  } | r| d | 7} qn  |  j | | pd  |  j j |  j     x<   j  j  D]. } | j j! j  j" r|  j# | j j!  qqWd S)z
        Takes a model and creates a table for it in the database.
        Will also create any accompanying indexes or unique constraints.
        Nr   checkz CHECK (%s)z %sz_fk_%(to_table)s_%(to_column)s to_table	to_columnz%s %s	AutoFieldBigAutoFieldc                s%   g  |  ] }   j  j |  j  q Sr   )r   	get_fieldcolumn)r
   r   )r   r   r   
<listcomp>  s   	 z9BaseDatabaseSchemaEditor.create_model.<locals>.<listcomp>tablez, 
definition)rb   rc   )$r   local_fieldsrQ   rB   r   Zdb_type_suffixextendremote_fielddb_constraintr   db_tablerd   
field_namere   r   supports_foreign_keysr   r.   _create_fk_sqlsql_create_inline_fkr4   rU   r3   autoinc_sqlZunique_together_create_unique_sqlsql_create_tablejoinrL   rM   r!   _model_indexes_sqllocal_many_to_manythroughauto_createdcreate_model)r   r   Zcolumn_sqlsr(   r   rh   extra_paramsrO   Zcol_type_suffixr`   ra   rr   fieldscolumnsr&   rM   r   )r   r   rz      sX    
!"		! 	z%BaseDatabaseSchemaEditor.create_modelc             C   sm   x< | j  j D]. } | j j j  j r |  j | j j  q q W|  j |  j i |  j | j  j	  d 6 d S)z4
        Deletes a model from the database.
        rg   N)
r   rw   rk   rx   ry   delete_modelr!   sql_delete_tabler4   rm   )r   r   r   r   r   r   r~   1  s
    z%BaseDatabaseSchemaEditor.delete_modelc                s   t  d d   | D  } t  d d   | D  } x7 | j |  D]& } |  j   | i d d 6|  j  qB WxI | j |  D]8 }   f d d   | D } |  j |  j   |   q| Wd S)	z
        Deals with a model changing its unique_together.
        Note: The input unique_togethers must be doubly-nested, not the single-
        nested ["foo", "bar"] format.
        c             s   s   |  ] } t  |  Vq d  S)N)r/   )r
   r|   r   r   r   r   E  s    zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<genexpr>c             s   s   |  ] } t  |  Vq d  S)N)r/   )r
   r|   r   r   r   r   F  s    TrK   c                s%   g  |  ] }   j  j |  j  q Sr   )r   rd   re   )r
   r   )r   r   r   rf   L  s   	 zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)set
difference_delete_composed_indexsql_delete_uniquer!   rs   )r   r   Zold_unique_togetherZnew_unique_togetheroldsnewsr|   r}   r   )r   r   alter_unique_together?  s    $z.BaseDatabaseSchemaEditor.alter_unique_togetherc                s   t  d d   | D  } t  d d   | D  } x7 | j |  D]& } |  j   | i d d 6|  j  qB WxO | j |  D]> }   f d d   | D } |  j |  j   | d d	  q| Wd
 S)z
        Deals with a model changing its index_together.
        Note: The input index_togethers must be doubly-nested, not the single-
        nested ["foo", "bar"] format.
        c             s   s   |  ] } t  |  Vq d  S)N)r/   )r
   r|   r   r   r   r   U  s    z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<genexpr>c             s   s   |  ] } t  |  Vq d  S)N)r/   )r
   r|   r   r   r   r   V  s    Tindexc                s"   g  |  ] }   j  j |   q Sr   )r   rd   )r
   r   )r   r   r   rf   \  s   	 zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>suffix_idxN)r   r   r   sql_delete_indexr!   _create_index_sql)r   r   Zold_index_togetherZnew_index_togetherr   r   r|   field_namesr   )r   r   alter_index_togetherO  s    $z-BaseDatabaseSchemaEditor.alter_index_togetherc                s     f d d   | D } |  j    | |  } t |  d k rq t d t |    j j d j |  f   n  |  j |  j |   | d   d  S)Nc                s%   g  |  ] }   j  j |  j  q Sr   )r   rd   re   )r
   r   )r   r   r   rf   `  s   	 zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>   z1Found wrong number (%s) of constraints for %s(%s)z, r   )_constraint_nameslen
ValueErrorr   rm   ru   r!   _delete_constraint_sql)r   r   r|   Zconstraint_kwargsr&   r}   constraint_namesr   )r   r   r   _  s    		z/BaseDatabaseSchemaEditor._delete_composed_indexc             C   so   | | k s3 |  j  j j r7 | j   | j   k r7 d S|  j |  j i |  j |  d 6|  j |  d 6 d S)z6
        Renames the table a model points to.
        NZ	old_tableZ	new_table)r   r   Zignores_quoted_identifier_caselowerr!   sql_rename_tabler4   )r   r   Zold_db_tableZnew_db_tabler   r   r   alter_db_tablej  s    z'BaseDatabaseSchemaEditor.alter_db_tablec             C   sN   |  j  |  j i |  j | j j  d 6|  j |  d 6|  j |  d 6 d S)z;
        Moves a model's table between tablespaces
        rg   Zold_tablespaceZnew_tablespaceN)r!   sql_retablespace_tabler4   r   rm   )r   r   Zold_db_tablespaceZnew_db_tablespacer   r   r   alter_db_tablespacew  s    z,BaseDatabaseSchemaEditor.alter_db_tablespacec             C   s  | j  r. | j j j j r. |  j | j j  S|  j | | d d \ } } | d k r\ d S| j d |  j  } | d r | d | d 7} n  |  j	 i |  j
 | j j  d 6|  j
 | j  d 6| d	 6} |  j | |  |  j |  rP| j d k	 rP|  j i |  j
 | j j  d 6|  j i |  j
 | j  d 6d
 6} |  j |  n  | j r| j r|  j j |  j | | g   n  | j r|  j j j r| j r|  j j |  j | | d   n  |  j j j r|  j j   n  d S)z
        Creates a field on a model.
        Usually involves adding a column, but may involve adding a
        table instead (for M2M fields)
        rN   TNr   r^   z CHECK (%s)rg   re   rh   changesz_fk_%(to_table)s_%(to_column)s)r	   rk   rx   r   ry   rz   rQ   rB   r   sql_create_columnr4   rm   re   r!   rD   r]   sql_alter_columnsql_alter_column_no_defaultdb_indexrK   r   r.   r   r   ro   rl   rp   connection_persists_old_columnsclose)r   r   r   rh   r(   rO   r&   r   r   r   	add_field  s2    
			"!"z"BaseDatabaseSchemaEditor.add_fieldc             C   s  | j  r. | j j j j r. |  j | j j  S| j d |  j  d d k rQ d S| j r |  j | | j	 g d d } x0 | D]% } |  j
 |  j |  j | |   q Wn  |  j i |  j | j j  d 6|  j | j	  d 6} |  j
 |  |  j j j r|  j j   n  d S)z
        Removes a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        r   r@   Nforeign_keyTrg   re   )r	   rk   rx   r   ry   r~   rB   r   r   re   r!   r   sql_delete_fksql_delete_columnr4   rm   r   r   r   )r   r   r   fk_namesfk_namer&   r   r   r   remove_field  s    	&	z%BaseDatabaseSchemaEditor.remove_fieldc       	   	   C   s  | j  d |  j  } | d } | j  d |  j  } | d } | d k rY | j d k st | d k r | j d k r t d | | f   n | d k r | d k r | j j r | j j r | j j j j r | j j j j r |  j | | | |  S| d k rQ| d k rQ| j j rQ| j j rQ| j j j j rQ| j j j j rQd S| d k si| d k rt d | | f   n  |  j | | | | | | | |  d S)aE  
        Allows a field's type, uniqueness, nullability, default, column,
        constraints etc. to be modified.
        Requires a copy of the old field as well so we can only perform
        changes that are required.
        If strict is true, raises errors if the old column does not match old_field precisely.
        r   r@   NzqCannot alter field %s into %s - they do not properly define db_type (are you using a badly-written custom field?)zCannot alter field %s into %s - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields))	rB   r   rk   r   rx   r   ry   _alter_many_to_many_alter_field)	r   r   r   r   strictold_db_paramsold_typenew_db_paramsnew_typer   r   r   alter_field  s2    	

z$BaseDatabaseSchemaEditor.alter_fieldc	       #   	   C   s  t    }	 | j r | j r |  j | | j g d d }
 | r| t |
  d k r| t d t |
  | j j | j f   n  xC |
 D]8 } |	 j	 | j f  |  j
 |  j |  j | |   q Wn  | j r|| j s | j r|| j r||  j | | j g d d } | rIt |  d k rIt d t |  | j j | j f   n  x0 | D]% } |  j
 |  j |  j | |   qPWn  | j r| j r| | k rxw t | |  D]c \ } } |  j | j | j j g d d } x0 | D]( } |  j
 |  j |  j | j |   qWqWn  | j r| j r| j r| j oA| j r|  j | | j g d d } x0 | D]% } |  j
 |  j |  j | |   qjWn  | d | d k rH| d rH|  j | | j g d d } | rt |  d k rt d	 t |  | j j | j f   n  x0 | D]% } |  j
 |  j |  j | |   qWn  | j | j k r|  j
 |  j | j j | | |   n  g  } g  } g  } | | k r|  j | j j | | |  \ } } | j |  | j |  n  |  j |  } |  j |  } | | k o$| d
 k	 o$|  j |  } | r|  j j j r| j |  j i |  j  | j  d 6| d 6|  j! |  d 6g  f  q| j |  j i |  j  | j  d 6| d 6d d 6| g f  n  | j" | j" k rq|  j j j# r| j$   d  k rqq| j" r:| j |  j% i |  j  | j  d 6| d 6g  f  qq| j |  j& i |  j  | j  d 6| d 6g  f  n  | j'   o| j" o| j" } | s| r| s| | } n  |  j j j( r | r t) t* |    \ } } d j+ |  t, | g   f g } n  xH | D]@ \ } } |  j
 |  j- i |  j  | j j  d 6| d 6|  qW| r|  j
 |  j. i |  j  | j j  d 6|  j  | j  d 6d d 6| g  xK | D]@ \ } } |  j
 |  j- i |  j  | j j  d 6| d 6|  qWqn  | rx' | D] \ } } |  j
 | |  qWn  | j r/| j sK| j rm| j rm| j rm|  j
 |  j/ | | j g   n  | j r| j r| j r| j o| j r|  j
 |  j0 | | g d d  n  g  } | j r | j r | | k r | j t | |   n  | j r	| j r	|  j | d d } | ret |  d k ret d t |  | j j f   n  x- | D]% } |  j
 |  j |  j1 | |   qlW|  j
 |  j2 i |  j  | j j  d 6|  j  |  j3 | | j g d d  d 6|  j  | j  d 6 | j t | |   n  x | D] \ } } | j j4 d |  j  }  |  d }! |  j | j j j | j | j |!  \ } } |  j
 |  j- i |  j  | j j j  d 6| d d 6| d  x$ | D] \ } } |  j
 | |  q	Wq	W| j r*
|	 s
| j s
| j r*
| j r*
|  j
 |  j5 | | d   n  | j r
| j r
| | k r
xH | j6 j j7 D]4 }" |" j8 sX
|  j
 |  j5 |" j |" j d   qX
qX
Wn  | d | d k r$| d r$|  j
 |  j9 i |  j  | j j  d 6|  j  |  j3 | | j g d d  d 6|  j  | j  d 6| d d 6 n  | r|  j- i |  j  | j j  d 6|  j: i |  j  | j  d 6| d 6d 6} |  j
 |  n  |  j j j; r|  j j<   n  d
 S)!z<Actually perform a "physical" (non-ManyToMany) field update.r   Tr   z<Found wrong number (%s) of foreign key constraints for %s.%srK   z7Found wrong number (%s) of unique constraints for %s.%sr   r^   z6Found wrong number (%s) of check constraints for %s.%sNre   r@   r]   z%s	CharField	TextFieldz, rg   r   r   _uniqrI   z0Found wrong number (%s) of PK constraints for %sZ_pkr5   r}   r   r   z_fk_%(to_table)s_%(to_column)sZ_fk_check)r   r   )=r   rk   rl   r   re   r   r   r   rm   addr!   r   r   rK   rI   r   r   Zrelated_modelr   r   r   sql_delete_check_rename_field_sql_alter_column_type_sqlr.   rj   rE   rD   r   r   rF   sql_alter_column_defaultr4   rG   rC   rJ   rU   sql_alter_column_nullsql_alter_column_not_nullrT   Zsupports_combined_altersr/   r   ru   sumr   sql_update_with_defaultrs   r   sql_delete_pksql_create_pk_create_index_namerB   rp   r   r   r	   sql_create_checkr   r   r   )#r   r   r   r   r   r   r   r   r   Zfks_droppedr   r   r   Zconstraint_nameZ_old_relZnew_relZrel_fk_namesZindex_names
index_nameZactionsZnull_actionsZpost_actionsfragmentZother_actionsZold_defaultZnew_defaultZneeds_database_defaultZfour_way_default_alterationr&   r(   Zrels_to_updateZold_relZrel_db_paramsZrel_typerelr   r   r   r     s^   			&&		&-
&		&(					$		
	"
%	#	(
'				,	(		z%BaseDatabaseSchemaEditor._alter_fieldc             C   s1   |  j  i |  j | j  d 6| d 6g  f g  f S)a  
        Hook to specialize column type alteration for different backends,
        for cases when a creation type is different to an alteration type
        (e.g. SERIAL in PostgreSQL, PostGIS fields).

        Should return two things; an SQL fragment of (sql, params) to insert
        into an ALTER TABLE statement, and a list of extra (sql, params) tuples
        to run once the field is altered.
        re   r@   )sql_alter_column_typer4   re   )r   rg   r   r   r   r   r   r   r     s
    	z/BaseDatabaseSchemaEditor._alter_column_type_sqlc             C   s   | j  j j j | j  j j j k rX |  j | j  j | j  j j j | j  j j j  n  |  j | j  j | j  j j j | j    | j  j j j | j     |  j | j  j | j  j j j | j    | j  j j j | j     d S)z=
        Alters M2Ms to repoint their to= endpoints.
        N)	rk   rx   r   rm   r   r   rd   Zm2m_reverse_field_nameZm2m_field_name)r   r   r   r   r   r   r   r   r     s    $		z,BaseDatabaseSchemaEditor._alter_many_to_manyr*   c       	      C   s  t  |  d k rO | rO t d | j j |  j | d  f |  j j j    S| j j j d d  j d d  } d |  j | |  } |  j j j   p d	 } d
 | | d | | f j d d  j d d  } t  |  | k r#d | d | | f } d | d | t  |   | f } n  | d d k rF| d d  } n  t  |  | k rt	 j
 t |   j   d |  } n  | d j   rd | d d  } n  | S)zI
        Generates a unique name for an index/unique constraint.
        r   z%s_%sr   "r*   ._z_%s   z	%s_%s%s%sz_%s%s%sz%s%sNzD%s)r   r   r   rm   r?   r   r3   Zmax_name_lengthreplacer7   r8   r   r:   isdigit)	r   r   column_namesr   Z
table_nameZindex_unique_name
max_lengthr   partr   r   r   r   '  s(     $'(z+BaseDatabaseSchemaEditor._create_index_namec                s  t  |  d k r> | d j r>   j j j | d j  } n0 | j j rh   j j j | j j  } n d } | r d | } n  d d   | D } | p   j } | i   j | j j  d 6  j   j	 | | d |  d	 6d
 j
   f d d   | D  d 6| d 6S)z
        Return the SQL statement to create the index for one or several fields.
        `sql` can be specified if the syntax differs from the standard (GIS
        indexes, ...).
        r   r   r*   r_   c             S   s   g  |  ] } | j   q Sr   )re   )r
   r   r   r   r   rf   V  s   	 z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>rg   r   r5   z, c             3   s   |  ] }   j  |  Vq d  S)N)r4   )r
   re   )r   r   r   r   [  s    z=BaseDatabaseSchemaEditor._create_index_sql.<locals>.<genexpr>r}   r'   )r   rL   r   r3   rM   r   sql_create_indexr4   rm   r   ru   )r   r   r|   r   r&   rM   r}   r   r   )r   r   r   G  s    "#z*BaseDatabaseSchemaEditor._create_index_sqlc                s     j  j s%   j  j s%   j  j r) g  Sg  } xK   j  j D]= } |  j   |  r< | j |  j   | g d d  q< q< WxL   j  j D]> }   f d d   | D } | j |  j   | d d  q W| S)z}
        Return all index SQL statements (field indexes, index_together) for the
        specified model, as a list.
        r   r*   c                s"   g  |  ] }   j  j |   q Sr   )r   rd   )r
   r   )r   r   r   rf   l  s   	 z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   )	r   ZmanagedproxyZswappedri   _field_should_be_indexedr.   r   Zindex_together)r   r   outputr   r   r|   r   )r   r   rv   _  s    %)#z+BaseDatabaseSchemaEditor._model_indexes_sqlc             C   s   | j  o | j S)N)r   rK   )r   r   r   r   r   r   r   p  s    z1BaseDatabaseSchemaEditor._field_should_be_indexedc             C   sH   |  j  i |  j |  d 6|  j | j  d 6|  j | j  d 6| d 6S)Nrg   Z
old_columnZ
new_columnr@   )sql_rename_columnr4   re   )r   rg   r   r   r   r   r   r   r   s  s
    	z*BaseDatabaseSchemaEditor._rename_field_sqlc             C   s   | j  j } | j } | j j j  j } | j j } | i | d 6| d 6} |  j i |  j |  d 6|  j |  j | | g d |  d 6|  j |  d 6|  j |  d 6|  j |  d 6|  j j	 j
   d 6S)Nr`   ra   rg   r   r5   re   Z
deferrable)r   rm   re   Ztarget_fieldr   sql_create_fkr4   r   r   r3   Zdeferrable_sql)r   r   r   r   Z
from_tableZfrom_columnr`   ra   r   r   r   rp   {  s    		%z'BaseDatabaseSchemaEditor._create_fk_sqlc                sf     j  i   j | j j  d 6  j   j | | d d  d 6d j   f d d   | D  d 6S)	Nrg   r   r   r5   z, c             3   s   |  ] }   j  |  Vq d  S)N)r4   )r
   re   )r   r   r   r     s    z>BaseDatabaseSchemaEditor._create_unique_sql.<locals>.<genexpr>r}   )sql_create_uniquer4   r   rm   r   ru   )r   r   r}   r   )r   r   rs     s    	"z+BaseDatabaseSchemaEditor._create_unique_sqlc             C   s.   | i |  j  | j j  d 6|  j  |  d 6S)Nrg   r5   )r4   r   rm   )r   templater   r5   r   r   r   r     s    z/BaseDatabaseSchemaEditor._delete_constraint_sqlc          
   C   sF  | r t  |  n d } |  j j   % } |  j j j | | j j  }	 Wd QXg  }
 x |	 j   D] \ } } | d k s | | d k ra | d k	 r | d | k r qa n  | d k	 r | d | k r qa n  | d k	 r | d | k r qa n  | d k	 r| d | k rqa n  | d k	 r.| d r.qa n  |
 j |  qa qa W|
 S)zR
        Returns all constraint names matching the columns and conditions
        Nr}   rK   rI   r   r^   r   )	listr   r2   ZintrospectionZget_constraintsr   rm   itemsr.   )r   r   r   rK   rI   r   r   r^   r2   constraintsresultr5   Zinfodictr   r   r   r     s$    $z*BaseDatabaseSchemaEditor._constraint_names)?__name__
__module____qualname____doc__rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rq   r   r   r   r   r   r   r    r"   r!   r4   classmethodr?   rQ   rD   rG   rE   r1   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   rv   r   r   rp   rs   r   r   r   r   r   r   r      s|   		0	E
-* 
 	r   )r7   loggingr   Zdjango.db.backends.utilsr   Zdjango.db.transactionr   Zdjango.utilsr   r   Zdjango.utils.encodingr   	getLoggerr+   r   objectr   r   r   r   r   <module>   s   	