o 3a Q@s|ddlZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZdd lmZGd d d eZdS) N)Decimal)Apps)NotSupportedError)BaseDatabaseSchemaEditor) Statement) strip_quotes)UniqueConstraint)atomiccseZdZdZdZdZdZdZfddZfdd Z d d Z d&d dZ d'fdd Z d(fdd Z d)ddZd'fdd ZddZddZ d(ddZddZfd d!Zfd"d#Zd$d%ZZS)*DatabaseSchemaEditorzDROP TABLE %(table)sNzEREFERENCES %(to_table)s (%(to_column)s) DEFERRABLE INITIALLY DEFERREDz7CREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)zDROP INDEX %(name)scs|js tdtS)NzSQLite schema editor cannot be used while foreign key constraint checks are enabled. Make sure to disable them before entering a transaction.atomic() context because SQLite does not support disabling them in the middle of a multi-statement transaction.) connectiondisable_constraint_checkingrsuper __enter__self __class__C/usr/lib/python3/dist-packages/django/db/backends/sqlite3/schema.pyrs  zDatabaseSchemaEditor.__enter__cs(|jt||||jdSN)r check_constraintsr __exit__enable_constraint_checking)rexc_type exc_value tracebackrrrr"s zDatabaseSchemaEditor.__exit__cCsz ddl}||}WntyYn |jyYnwt|tr)tt|St|tt tfr5t|St|trBd| ddS|durHdSt|t t t frVd|Std|t|f)Nrz'%s''z''NULLzX'%s'z*Cannot quote parameter value %r of type %s)sqlite3adapt ImportErrorProgrammingError isinstanceboolstrintrfloatreplacebytes bytearray memoryviewhex ValueErrortype)rvaluerrrr quote_value's&     z DatabaseSchemaEditor.quote_valueFc Cs|jG}|jj|D]6}|r|j|krq |jj||j}|D]}|d\}} ||krB|dus8| |krBWddSq$q WddS1sOwYdS)a Return whether or not the provided table name is referenced by another one. If `column_name` is specified, only references pointing to that column are considered. If `ignore_self` is True, self-referential constraints are ignored. foreign_keyNTF)r cursor introspectionget_table_listname_get_foreign_key_constraintsvalues) r table_name column_name ignore_selfr1 other_table constraints constraintconstraint_tableconstraint_columnrrr_is_referenced_by_fk_constraintCs$      z4DatabaseSchemaEditor._is_referenced_by_fk_constraintTcsh|jjjs*|r*||r*|jjrtd||jt||||j dSt|||dS)NzRenaming the %r table while in a transaction is not supported on SQLite < 3.26 because it would break referential integrity. Try adding `atomic = False` to the Migration class.) r features!supports_atomic_references_renamer?in_atomic_blockrrr alter_db_tabler )rmodel old_db_table new_db_tabledisable_constraintsrrrrCVs  z#DatabaseSchemaEditor.alter_db_tablec s|||sdS|j}|jj}|\}}|j|kr|jjjs|j||ddr|jj r5t d|jj|ft |jj bt j||||d|jC} | dd} | dd|} |d } | |} | | }| d | |f| d | d | d | d Wdn1swYWdn1swY|j} | dWddS1swYdSt j||||ddS)NT)r9zRenaming the %r.%r column while in a transaction is not supported on SQLite < 3.26 because it would break referential integrity. Try adding `atomic = False` to the Migration class.)strictzPRAGMA schema_versionrzPRAGMA writable_schema = 1z REFERENCES "%s" ("%%s") z3UPDATE sqlite_master SET sql = replace(sql, %s, %s)zPRAGMA schema_version = %dzPRAGMA writable_schema = 0zPRAGMA integrity_checkVACUUM)_field_should_be_alteredr4_metadb_tableget_attname_columnr r@rAr?rBrr aliasr alter_fieldr1executefetchone)rrD old_field new_fieldrHold_field_namer7_old_column_namer1schema_versionreferences_templatenew_column_namesearch replacementrrrrPesF           "z DatabaseSchemaEditor.alter_fieldc sHfddfddjjD}fddjjD}id}t|dds0|rMt|d ddrMt|D]\}} | jrLd| _| }| jrL||=|| j=q6|re|||j<|j se|j re  |||j<|r|\} } | | jd| | jd| || j<| jr| jsd | j  | d } | || j<n | j|| j<| j| j<r|j=|j=j rĈjjjjrĈjjSt} fd d jjD}fdd jjD}jj}rfdd |D}tjj}t|}jjjj||||| d}tdd|}||d<j|d<tjjj|t|}jjdt jj||||| d}tdd|}||d<j|d<tdjjj|}!|"d|jjd#fdd|Dd#|$jjfjddj%||jjjjddj&D]}"|qg_&|rd|_dSdS)a| Shortcut to transform a model from old_model into new_model This follows the correct procedure to perform non-rename or column addition operations based on SQLite's documentation https://www.sqlite.org/lang_altertable.html#caution The essential steps are: 1. Create a table with the updated definition called "new__app_model" 2. Copy the data from the existing "app_model" table to the new table 3. Drop the "app_model" table 4. Rename the "new__app_model" table to "app_model" 5. Restore any index of the previous "app_model" table. cs|jo|jjuSr) is_relation remote_fieldrD)f)rDrris_self_referentialsz?DatabaseSchemaEditor._remake_table..is_self_referentialcs$i|]}|j|r|n|qSr)r4clone.0r_)r`rr sz6DatabaseSchemaEditor._remake_table..csi|] }|j|jqSr)column quote_namerbrrrrdsN primary_keyFrIzcoalesce(%(col)s, %(default)s))coldefaultcg|] }fdd|DqS)cg|]}||qSrgetrcnrename_mappingrr ADatabaseSchemaEditor._remake_table...r)rcuniquerprrrrz6DatabaseSchemaEditor._remake_table..crj)crkrrlrnrprrrrrsrtrrcindexrprrrrrvcsg|] }j|jvr|qSr)r4fieldsrw delete_fieldrrrrs  ) app_labelrMunique_togetherindex_togetherindexesr;appsMetar __module__znew__%szNew%s%INSERT INTO %s (%s) SELECT %s FROM %s, c3s|]}|VqdSr)rf)rcxrrr sz5DatabaseSchemaEditor._remake_table..)handle_autom2m)rGT)'rLlocal_concrete_fieldsgetattrlistitemsrg auto_createdrer4 many_to_manyconcreter/effective_defaultpopnullrfr^through delete_modelrr}r~rr;copydeepcopyr|rMr-r object_name __bases__r create_modelrQjoinr6rC deferred_sql)rrD create_fieldr{rPbodymappingrestore_pk_fieldr4fieldrSrTcase_sqlrr}r~rr; body_copy meta_contentsmeta new_modelsqlr)r{r`rDrqrr _remake_tables                           z"DatabaseSchemaEditor._remake_tablecsj|r t|dS||jd||jjit|jD]}t |t r2| |jjr2|j |qdS)Ntable) r rrQsql_delete_tablerfrLrMrrr"rreferences_tableremove)rrDrrrrrr5s z!DatabaseSchemaEditor.delete_modelcCs2|jr|jjjjr||jjS|j||ddS)z Create a field on a model. Usually involves adding a column, but may involve adding a table instead (for M2M fields). )rN)rr^rrLrrrrrDrrrr add_fieldBszDatabaseSchemaEditor.add_fieldcCsT|jr|jjjjr||jjdSdS|j|jdddur!dS|j||ddS)z Remove a field from a model. Usually involves deleting a column, but for M2Ms may involve deleting a table. )r r-Nrz) rr^rrLrr db_parametersr rrrrr remove_fieldLs z!DatabaseSchemaEditor.remove_fieldc Cs:|jjjr0|j|jkr0||||||kr0|jr|js0|jr#|js0|||j j |||S|j |||fd|j r||krt } |jj } | jD]&} | j|krRqJ| jsb| j|jkra| | jqJ|jrp| jj jrp| | jqJ|jr| jD]} | j|krqw| jjj jr| | jjqw| D] } | | qdSdSdS)z3Perform a "physical" (non-ManyToMany) field update.rPN)r r@can_alter_table_rename_columnre column_sqlr^ db_constraintrQ_rename_field_sqlrLrMrrusetrDrelated_objects related_modelr field_namer4addrgrr)rrDrSrTold_typenew_type old_db_params new_db_paramsrHrelated_modelsoptsr^rrrrr _alter_field^sJ           z!DatabaseSchemaEditor._alter_fieldc Cs|jjjj|jjjjkr)|j|jj|jjj||jjj|fddS||jj|d| |jjjjd d| | gd d| | g| |jjjjf| |jjdS)z*Alter M2Ms to repoint their to= endpoints.rNrrid)r^rrLrMr get_fieldm2m_reverse_field_namerrQrfrm2m_column_namem2m_reverse_namer)rrDrSrTrHrrr_alter_many_to_manys0 z(DatabaseSchemaEditor._alter_many_to_manyc0t|tr|jrt||dS||dSr)r"r conditionr add_constraintrrrDr<rrrrz#DatabaseSchemaEditor.add_constraintcrr)r"rrr remove_constraintrrrrrrrz&DatabaseSchemaEditor.remove_constraintcCsd|S)Nz COLLATE r)r collationrrr _collate_sqlsz!DatabaseSchemaEditor._collate_sql)NF)T)F)NNN)__name__r __qualname__r sql_create_fksql_create_inline_fksql_create_uniquesql_delete_uniquerrr/r?rCrPrrrrrrrrr __classcell__rrrrr s.    )(   $ # r )rdecimalrdjango.apps.registryr django.dbrdjango.db.backends.base.schemar!django.db.backends.ddl_referencesrdjango.db.backends.utilsrdjango.db.modelsrdjango.db.transactionr r rrrrs