tests running the operations and making sure they do what they say they do each test looks at their state changing and then their database operation both forwards and backwards tests the createmodel operation most other tests use this operation as part of setup so check failures here first test the state alteration test the database alteration and test reversal and deconstruction and default manager not in set tests the createmodel operation directly followed by an alteruniquetogether bug 22844 sqlite remake issues test the database alteration test the creation of a model with a manytomany field and the autocreated through model test the state alteration test the database alteration make sure the m2m field actually works and test reversal creation of models with a fk to a pk with dbcollation collation connection features testcollations getnondefault if not collation self skiptestlanguage collations are not supported applabel testcfkmtopkfdbc operations migrations createmodel pony id models charfield primarykeytrue maxlength10 dbcollationcollation projectstate self applyoperationsapplabel projectstate operations foreignkey newstate projectstate clone operation migrations createmodel rider id models autofieldprimarykeytrue pony models foreignkeypony models cascade operation stateforwardsapplabel newstate with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertcolumncollationfapplabelrider ponyid collation reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate onetoonefield newstate projectstate clone operation migrations createmodel shetlandpony pony models onetoonefieldpony models cascade primarykeytrue cuteness models integerfielddefault1 operation stateforwardsapplabel newstate with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertcolumncollationfapplabelshetlandpony ponyid collation reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate def testcreatemodelinheritanceself projectstate self setuptestmodeltestcrmoih test the state alteration operation migrations createmodel shetlandpony ponyptr models onetoonefield testcrmoih pony models cascade autocreatedtrue primarykeytrue tofieldid serializefalse cuteness models integerfielddefault1 newstate projectstate clone operation stateforwardstestcrmoih newstate self assertintestcrmoih shetlandpony newstate models test the database alteration self asserttablenotexiststestcrmoihshetlandpony with connection schemaeditor as editor operation databaseforwardstestcrmoih editor projectstate newstate self asserttableexiststestcrmoihshetlandpony and test reversal with connection schemaeditor as editor operation databasebackwards testcrmoih editor newstate projectstate self asserttablenotexiststestcrmoihshetlandpony def testcreateproxymodelself projectstate self setuptestmodeltestcrprmo test the state alteration operation migrations createmodel proxypony optionsproxy true basestestcrprmo pony self assertequaloperation describe create proxy model proxypony newstate projectstate clone operation stateforwardstestcrprmo newstate self assertintestcrprmo proxypony newstate models test the database alteration self asserttablenotexiststestcrprmoproxypony self asserttableexiststestcrprmopony with connection schemaeditor as editor operation databaseforwardstestcrprmo editor projectstate newstate self asserttablenotexiststestcrprmoproxypony self asserttableexiststestcrprmopony and test reversal with connection schemaeditor as editor operation databasebackwards testcrprmo editor newstate projectstate self asserttablenotexiststestcrprmoproxypony self asserttableexiststestcrprmopony and deconstruction definition operation deconstruct self assertequaldefinition0 createmodel self assertequaldefinition1 self assertequalsorteddefinition2 bases fields name options def testcreateunmanagedmodelself projectstate self setuptestmodeltestcrummo test the state alteration operation migrations createmodel unmanagedpony optionsproxy true basestestcrummo pony self assertequaloperation describe create proxy model unmanagedpony newstate projectstate clone operation stateforwardstestcrummo newstate self assertintestcrummo unmanagedpony newstate models test the database alteration self asserttablenotexiststestcrummounmanagedpony self asserttableexiststestcrummopony with connection schemaeditor as editor operation databaseforwardstestcrummo editor projectstate newstate self asserttablenotexiststestcrummounmanagedpony self asserttableexiststestcrummopony and test reversal with connection schemaeditor as editor operation databasebackwards testcrummo editor newstate projectstate self asserttablenotexiststestcrummounmanagedpony self asserttableexiststestcrummopony skipunlessdbfeaturesupportstablecheckconstraints def testcreatemodelwithconstraintself where models qpinkgt2 checkconstraint models checkconstraint checkwhere nametestconstraintponypinkgt2 operation migrations createmodel pony id models autofieldprimarykeytrue pink models integerfielddefault3 optionsconstraints checkconstraint test the state alteration projectstate projectstate newstate projectstate clone operation stateforwardstestcrmo newstate self assertequal lennewstate modelstestcrmo pony optionsconstraints 1 test database alteration self asserttablenotexiststestcrmopony with connection schemaeditor as editor operation databaseforwardstestcrmo editor projectstate newstate self asserttableexiststestcrmopony with connection cursor as cursor with self assertraisesintegrityerror cursor executeinsert into testcrmopony id pink values 1 1 test reversal with connection schemaeditor as editor operation databasebackwardstestcrmo editor newstate projectstate self asserttablenotexiststestcrmopony test deconstruction definition operation deconstruct self assertequaldefinition0 createmodel self assertequaldefinition1 self assertequaldefinition2optionsconstraints checkconstraint skipunlessdbfeaturesupportstablecheckconstraints def testcreatemodelwithbooleanexpressionincheckconstraintself applabel testcrmobechc rawsqlconstraint models checkconstraint checkmodels expressions rawsql price s 1000 outputfieldmodels booleanfield namefapplabelpricelt1000raw wrapperconstraint models checkconstraint checkmodels expressions expressionwrapper models qpricegt500 models qpricelt500 outputfieldmodels booleanfield namefapplabelpriceneq500wrap operation migrations createmodel product id models autofieldprimarykeytrue price models integerfieldnulltrue optionsconstraints rawsqlconstraint wrapperconstraint projectstate projectstate newstate projectstate clone operation stateforwardsapplabel newstate add table self asserttablenotexistsapplabel with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self asserttableexistsfapplabelproduct insertsql finsert into applabelproduct id price values d d with connection cursor as cursor with self assertraisesintegrityerror cursor executeinsertsql 1 1000 cursor executeinsertsql 1 999 with self assertraisesintegrityerror cursor executeinsertsql 2 500 cursor executeinsertsql 2 499 def testcreatemodelwithpartialuniqueconstraintself partialuniqueconstraint models uniqueconstraint fieldspink conditionmodels qweightgt5 nametestconstraintponypinkforweightgt5uniq operation migrations createmodel pony id models autofieldprimarykeytrue pink models integerfielddefault3 weight models floatfield optionsconstraints partialuniqueconstraint test the state alteration projectstate projectstate newstate projectstate clone operation stateforwardstestcrmo newstate self assertequal lennewstate modelstestcrmo pony optionsconstraints 1 test database alteration self asserttablenotexiststestcrmopony with connection schemaeditor as editor operation databaseforwardstestcrmo editor projectstate newstate self asserttableexiststestcrmopony test constraint works pony newstate apps getmodeltestcrmo pony pony objects createpink1 weight4 0 pony objects createpink1 weight4 0 pony objects createpink1 weight6 0 if connection features supportspartialindexes with self assertraisesintegrityerror pony objects createpink1 weight7 0 else pony objects createpink1 weight7 0 test reversal with connection schemaeditor as editor operation databasebackwardstestcrmo editor newstate projectstate self asserttablenotexiststestcrmopony test deconstruction definition operation deconstruct self assertequaldefinition0 createmodel self assertequaldefinition1 self assertequal definition2optionsconstraints partialuniqueconstraint def testcreatemodelwithdeferreduniqueconstraintself deferreduniqueconstraint models uniqueconstraint fieldspink namedeferrablepinkconstraint deferrablemodels deferrable deferred operation migrations createmodel pony id models autofieldprimarykeytrue pink models integerfielddefault3 optionsconstraints deferreduniqueconstraint projectstate projectstate newstate projectstate clone operation stateforwardstestcrmo newstate self assertequal lennewstate modelstestcrmo pony optionsconstraints 1 self asserttablenotexiststestcrmopony create table with connection schemaeditor as editor operation databaseforwardstestcrmo editor projectstate newstate self asserttableexiststestcrmopony pony newstate apps getmodeltestcrmo pony pony objects createpink1 if connection features supportsdeferrableuniqueconstraints unique constraint is deferred with transaction atomic obj pony objects createpink1 obj pink 2 obj save constraint behavior can be changed with set constraints with self assertraisesintegrityerror with transaction atomic connection cursor as cursor quotedname connection ops quotename deferreduniqueconstraint name cursor executeset constraints s immediate quotedname obj pony objects createpink1 obj pink 3 obj save else pony objects createpink1 reversal with connection schemaeditor as editor operation databasebackwardstestcrmo editor newstate projectstate self asserttablenotexiststestcrmopony deconstruction definition operation deconstruct self assertequaldefinition0 createmodel self assertequaldefinition1 self assertequal definition2optionsconstraints deferreduniqueconstraint skipunlessdbfeaturesupportscoveringindexes def testcreatemodelwithcoveringuniqueconstraintself coveringuniqueconstraint models uniqueconstraint fieldspink includeweight nametestconstraintponypinkcoveringweight operation migrations createmodel pony id models autofieldprimarykeytrue pink models integerfielddefault3 weight models floatfield optionsconstraints coveringuniqueconstraint projectstate projectstate newstate projectstate clone operation stateforwardstestcrmo newstate self assertequal lennewstate modelstestcrmo pony optionsconstraints 1 self asserttablenotexiststestcrmopony create table with connection schemaeditor as editor operation databaseforwardstestcrmo editor projectstate newstate self asserttableexiststestcrmopony pony newstate apps getmodeltestcrmo pony pony objects createpink1 weight4 0 with self assertraisesintegrityerror pony objects createpink1 weight7 0 reversal with connection schemaeditor as editor operation databasebackwardstestcrmo editor newstate projectstate self asserttablenotexiststestcrmopony deconstruction definition operation deconstruct self assertequaldefinition0 createmodel self assertequaldefinition1 self assertequal definition2optionsconstraints coveringuniqueconstraint def testcreatemodelmanagersself projectstate self setuptestmodeltestcmoma test the state alteration operation migrations createmodel food fields id models autofieldprimarykeytrue managers foodqs foodqueryset asmanager foodmgr foodmanagera b foodmgrkwargs foodmanagerx y 3 4 self assertequaloperation describe create model food newstate projectstate clone operation stateforwardstestcmoma newstate self assertintestcmoma food newstate models managers newstate modelstestcmoma food managers self assertequalmanagers00 foodqs self assertisinstancemanagers01 models manager self assertequalmanagers10 foodmgr self assertisinstancemanagers11 foodmanager self assertequalmanagers11 args a b 1 2 self assertequalmanagers20 foodmgrkwargs self assertisinstancemanagers21 foodmanager self assertequalmanagers21 args x y 3 4 def testdeletemodelself projectstate self setuptestmodeltestdlmo test the state alteration operation migrations deletemodelpony self assertequaloperation describe delete model pony self assertequaloperation migrationnamefragment deletepony newstate projectstate clone operation stateforwardstestdlmo newstate self assertnotintestdlmo pony newstate models test the database alteration self asserttableexiststestdlmopony with connection schemaeditor as editor operation databaseforwardstestdlmo editor projectstate newstate self asserttablenotexiststestdlmopony and test reversal with connection schemaeditor as editor operation databasebackwardstestdlmo editor newstate projectstate self asserttableexiststestdlmopony and deconstruction definition operation deconstruct self assertequaldefinition0 deletemodel self assertequaldefinition1 self assertequallistdefinition2 name def testdeleteproxymodelself projectstate self setuptestmodeltestdlprmo proxymodeltrue test the state alteration operation migrations deletemodelproxypony newstate projectstate clone operation stateforwardstestdlprmo newstate self assertintestdlprmo proxypony projectstate models self assertnotintestdlprmo proxypony newstate models test the database alteration self asserttableexiststestdlprmopony self asserttablenotexiststestdlprmoproxypony with connection schemaeditor as editor operation databaseforwardstestdlprmo editor projectstate newstate self asserttableexiststestdlprmopony self asserttablenotexiststestdlprmoproxypony and test reversal with connection schemaeditor as editor operation databasebackwards testdlprmo editor newstate projectstate self asserttableexiststestdlprmopony self asserttablenotexiststestdlprmoproxypony def testdeletemtimodelself projectstate self setuptestmodeltestdlmtimo mtimodeltrue test the state alteration operation migrations deletemodelshetlandpony newstate projectstate clone operation stateforwardstestdlmtimo newstate self assertintestdlmtimo shetlandpony projectstate models self assertnotintestdlmtimo shetlandpony newstate models test the database alteration self asserttableexiststestdlmtimopony self asserttableexiststestdlmtimoshetlandpony self assertcolumnexiststestdlmtimoshetlandpony ponyptrid with connection schemaeditor as editor operation databaseforwards testdlmtimo editor projectstate newstate self asserttableexiststestdlmtimopony self asserttablenotexiststestdlmtimoshetlandpony and test reversal with connection schemaeditor as editor operation databasebackwards testdlmtimo editor newstate projectstate self asserttableexiststestdlmtimopony self asserttableexiststestdlmtimoshetlandpony self assertcolumnexiststestdlmtimoshetlandpony ponyptrid def testrenamemodelself projectstate self setuptestmodeltestrnmo relatedmodeltrue test the state alteration operation migrations renamemodelpony horse self assertequaloperation describe rename model pony to horse self assertequaloperation migrationnamefragment renameponyhorse test initial state and database self assertintestrnmo pony projectstate models self assertnotintestrnmo horse projectstate models self asserttableexiststestrnmopony self asserttablenotexiststestrnmohorse if connection features supportsforeignkeys self assertfkexists testrnmorider ponyid testrnmopony id self assertfknotexists testrnmorider ponyid testrnmohorse id migrate forwards newstate projectstate clone newstate self applyoperationstestrnmo newstate operation test new state and database self assertnotintestrnmo pony newstate models self assertintestrnmo horse newstate models renamemodel also repoints all incoming fks and m2ms self assertequal newstate modelstestrnmo rider fieldspony remotefield model testrnmo horse self asserttablenotexiststestrnmopony self asserttableexiststestrnmohorse if connection features supportsforeignkeys self assertfknotexists testrnmorider ponyid testrnmopony id self assertfkexists testrnmorider ponyid testrnmohorse id migrate backwards originalstate self unapplyoperations testrnmo projectstate operation test original state and database self assertintestrnmo pony originalstate models self assertnotintestrnmo horse originalstate models self assertequal originalstate modelstestrnmo rider fieldspony remotefield model pony self asserttableexiststestrnmopony self asserttablenotexiststestrnmohorse if connection features supportsforeignkeys self assertfkexists testrnmorider ponyid testrnmopony id self assertfknotexists testrnmorider ponyid testrnmohorse id and deconstruction definition operation deconstruct self assertequaldefinition0 renamemodel self assertequaldefinition1 self assertequaldefinition2 oldname pony newname horse def testrenamemodelstateforwardsself state projectstate state addmodelmodelstatemigrations foo operation migrations renamemodelfoo bar operation stateforwardsmigrations state self assertnotinapps state dict self assertnotinmigrations foo state models self assertinmigrations bar state models now with apps cached apps state apps operation migrations renamemodelbar foo operation stateforwardsmigrations state self assertisstate apps apps self assertnotinmigrations bar state models self assertinmigrations foo state models def testrenamemodelwithselfreferentialfkself projectstate self setuptestmodeltestrmwsrf relatedmodeltrue test the state alteration operation migrations renamemodelrider horserider self assertequaloperation describe rename model rider to horserider newstate projectstate clone operation stateforwardstestrmwsrf newstate self assertnotintestrmwsrf rider newstate models self assertintestrmwsrf horserider newstate models remember renamemodel also repoints all incoming fks and m2ms self assertequal self newstate modelstestrmwsrf horserider fieldsfriend remotefield model horserider newstate apps getmodeltestrmwsrf horserider self assertis horserider meta getfieldhorserider remotefield model horserider test the database alteration self asserttableexiststestrmwsrfrider self asserttablenotexiststestrmwsrfhorserider if connection features supportsforeignkeys self assertfkexists testrmwsrfrider friendid testrmwsrfrider id self assertfknotexists testrmwsrfrider friendid testrmwsrfhorserider id with connection schemaeditor as editor operation databaseforwardstestrmwsrf editor projectstate newstate self asserttablenotexiststestrmwsrfrider self asserttableexiststestrmwsrfhorserider if connection features supportsforeignkeys self assertfknotexists testrmwsrfhorserider friendid testrmwsrfrider id self assertfkexists testrmwsrfhorserider friendid testrmwsrfhorserider id and test reversal with connection schemaeditor as editor operation databasebackwards testrmwsrf editor newstate projectstate self asserttableexiststestrmwsrfrider self asserttablenotexiststestrmwsrfhorserider if connection features supportsforeignkeys self assertfkexists testrmwsrfrider friendid testrmwsrfrider id self assertfknotexists testrmwsrfrider friendid testrmwsrfhorserider id def testrenamemodelwithsuperclassfkself projectstate self setuptestmodel testrmwsc relatedmodeltrue mtimodeltrue test the state alteration operation migrations renamemodelshetlandpony littlehorse self assertequal operation describe rename model shetlandpony to littlehorse newstate projectstate clone operation stateforwardstestrmwsc newstate self assertnotintestrmwsc shetlandpony newstate models self assertintestrmwsc littlehorse newstate models renamemodel shouldn t repoint the superclass s relations only local ones self assertequal projectstate modelstestrmwsc rider fieldspony remotefield model newstate modelstestrmwsc rider fieldspony remotefield model before running the migration we have a table for shetland pony not little horse self asserttableexiststestrmwscshetlandpony self asserttablenotexiststestrmwsclittlehorse if connection features supportsforeignkeys and the foreign key on rider points to pony not shetland pony self assertfkexists testrmwscrider ponyid testrmwscpony id self assertfknotexists testrmwscrider ponyid testrmwscshetlandpony id with connection schemaeditor as editor operation databaseforwardstestrmwsc editor projectstate newstate now we have a little horse table not shetland pony self asserttablenotexiststestrmwscshetlandpony self asserttableexiststestrmwsclittlehorse if connection features supportsforeignkeys but the foreign keys still point at pony not little horse self assertfkexists testrmwscrider ponyid testrmwscpony id self assertfknotexists testrmwscrider ponyid testrmwsclittlehorse id def testrenamemodelnorelationswithdbtablenoopself applabel testrmwdbtnoop projectstate self setuptestmodelapplabel dbtablemypony operation migrations renamemodelpony littlehorse newstate projectstate clone operation stateforwardsapplabel newstate with connection schemaeditor as editor self assertnumqueries0 operation databaseforwardsapplabel editor projectstate newstate skipunlessdbfeaturesupportsforeignkeys def testrenamemodelwithdbtableandfknoopself applabel testrmwdbtfk projectstate self setuptestmodel applabel dbtablemypony relatedmodeltrue newstate projectstate clone operation migrations renamemodelpony littlehorse operation stateforwardsapplabel newstate with connection schemaeditor as editor self assertnumqueries0 operation databaseforwardsapplabel editor projectstate newstate def testrenamemodelwithselfreferentialm2mself applabel testrenamemodelwithselfreferentialm2m projectstate self applyoperations applabel projectstate operations migrations createmodel reflexivepony fields id models autofieldprimarykeytrue ponies models manytomanyfieldself projectstate self applyoperations applabel projectstate operations migrations renamemodelreflexivepony reflexivepony2 pony projectstate apps getmodelapplabel reflexivepony2 pony pony objects create pony ponies addpony def testrenamemodelwithm2mself applabel testrenamemodelwithm2m projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue migrations createmodel pony fields id models autofieldprimarykeytrue riders models manytomanyfieldrider pony projectstate apps getmodelapplabel pony rider projectstate apps getmodelapplabel rider pony pony objects create rider rider objects create pony riders addrider projectstate self applyoperations applabel projectstate operations migrations renamemodelpony pony2 pony projectstate apps getmodelapplabel pony2 rider projectstate apps getmodelapplabel rider pony pony objects create rider rider objects create pony riders addrider self assertequalpony objects count 2 self assertequalrider objects count 2 self assertequal pony meta getfieldriders remotefield through objects count 2 def testrenamemodelwithm2mmodelsindifferentappswithsamenameself applabel1 testrmwm2m1 applabel2 testrmwm2m2 projectstate self applyoperations applabel1 projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue projectstate self applyoperations applabel2 projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue riders models manytomanyfieldfapplabel1 rider m2mtable fapplabel2riderriders self assertcolumnexistsm2mtable fromriderid self assertcolumnexistsm2mtable toriderid rider1 projectstate apps getmodelapplabel1 rider rider2 projectstate apps getmodelapplabel2 rider rider2 rider2 objects create rider2 riders addrider1 objects create rename model projectstate2 projectstate clone projectstate self applyoperations applabel2 projectstate operationsmigrations renamemodelrider pony m2mtable fapplabel2ponyriders self assertcolumnexistsm2mtable ponyid self assertcolumnexistsm2mtable riderid rider1 projectstate apps getmodelapplabel1 rider rider2 projectstate apps getmodelapplabel2 pony rider2 rider2 objects create rider2 riders addrider1 objects create self assertequalrider1 objects count 2 self assertequalrider2 objects count 2 self assertequal rider2 meta getfieldriders remotefield through objects count 2 reversal self unapplyoperations applabel2 projectstate2 operationsmigrations renamemodelrider pony m2mtable fapplabel2riderriders self assertcolumnexistsm2mtable toriderid self assertcolumnexistsm2mtable fromriderid def testrenamemodelwithdbtablerenamem2mself applabel testrmwdbrm2m projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue migrations createmodel pony fields id models autofieldprimarykeytrue riders models manytomanyfieldrider optionsdbtable pony newstate self applyoperations applabel projectstate operationsmigrations renamemodelpony pinkpony pony newstate apps getmodelapplabel pinkpony rider newstate apps getmodelapplabel rider pony pony objects create rider rider objects create pony riders addrider def testrenamem2mtargetmodelself applabel testrenamem2mtargetmodel projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue migrations createmodel pony fields id models autofieldprimarykeytrue riders models manytomanyfieldrider pony projectstate apps getmodelapplabel pony rider projectstate apps getmodelapplabel rider pony pony objects create rider rider objects create pony riders addrider projectstate self applyoperations applabel projectstate operations migrations renamemodelrider rider2 pony projectstate apps getmodelapplabel pony rider projectstate apps getmodelapplabel rider2 pony pony objects create rider rider objects create pony riders addrider self assertequalpony objects count 2 self assertequalrider objects count 2 self assertequal pony meta getfieldriders remotefield through objects count 2 def testrenamem2mthroughmodelself applabel testrenamethrough projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue migrations createmodel pony fields id models autofieldprimarykeytrue migrations createmodel ponyrider fields id models autofieldprimarykeytrue rider models foreignkey testrenamethrough rider models cascade pony models foreignkey testrenamethrough pony models cascade migrations addfield pony riders models manytomanyfield testrenamethrough rider throughtestrenamethrough ponyrider pony projectstate apps getmodelapplabel pony rider projectstate apps getmodelapplabel rider ponyrider projectstate apps getmodelapplabel ponyrider pony pony objects create rider rider objects create ponyrider objects createponypony riderrider projectstate self applyoperations applabel projectstate operations migrations renamemodelponyrider ponyrider2 pony projectstate apps getmodelapplabel pony rider projectstate apps getmodelapplabel rider ponyrider projectstate apps getmodelapplabel ponyrider2 pony pony objects first rider rider objects create ponyrider objects createponypony riderrider self assertequalpony objects count 1 self assertequalrider objects count 2 self assertequalponyrider objects count 2 self assertequalpony riders count 2 def testrenamem2mmodelafterrenamefieldself no no such column error means the column was renamed correctly tests the addfield operation test the state alteration test the database alteration and test reversal and deconstruction tests the addfield operation on textfield if not properly quoted digits would be interpreted as an int manual quoting is fragile and could trip on quotes refs xyz tests the addfield operation on textfield if not properly quoted digits would be interpreted as an int manual quoting is fragile and could trip on quotes refs xyz tests the addfield operation on textfieldbinaryfield if not properly quoted digits would be interpreted as an int manual quoting is fragile and could trip on quotes refs xyz sqlite returns buffermemoryview cast to bytes for checking column names that are sql keywords shouldn t cause problems when used in migrations 22168 tests the addfield operation s state alteration when preservedefault false test the state alteration test the database alteration and deconstruction the addfield operation can set and unset a database default applabel testadfldd tablename fapplabelpony projectstate self setuptestmodelapplabel operation migrations addfield pony height models floatfieldnulltrue dbdefault4 newstate projectstate clone operation stateforwardsapplabel newstate self assertequallennewstate modelsapplabel pony fields 6 field newstate modelsapplabel pony fieldsheight self assertequalfield default models notprovided self assertequalfield dbdefault value4 projectstate apps getmodelapplabel pony objects createweight4 self assertcolumnnotexiststablename height add field with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertcolumnexiststablename height newmodel newstate apps getmodelapplabel pony oldpony newmodel objects get self assertequaloldpony height 4 newpony newmodel objects createweight5 if not connection features canreturncolumnsfrominsert newpony refreshfromdb self assertequalnewpony height 4 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self assertcolumnnotexiststablename height deconstruction definition operation deconstruct self assertequaldefinition0 addfield self assertequaldefinition1 self assertequal definition2 field field modelname pony name height def testaddfielddatabasedefaultspecialcharescapingself applabel testadflddsce tablename fapplabelpony projectstate self setuptestmodelapplabel oldponypk projectstate apps getmodelapplabel pony objects createweight4 pk tests for dbdefault in tests with self subtestdbdefaultdbdefault operation migrations addfield pony specialchar models charfieldmaxlength1 dbdefaultdbdefault newstate projectstate clone operation stateforwardsapplabel newstate self assertequallennewstate modelsapplabel pony fields 6 field newstate modelsapplabel pony fieldsspecialchar self assertequalfield default models notprovided self assertequalfield dbdefault valuedbdefault self assertcolumnnotexiststablename specialchar with connection schemaeditor as editor operation databaseforwards applabel editor projectstate newstate self assertcolumnexiststablename specialchar newmodel newstate apps getmodelapplabel pony try newpony newmodel objects createweight5 if not connection features canreturncolumnsfrominsert newpony refreshfromdb self assertequalnewpony specialchar dbdefault oldpony newmodel objects getpkoldponypk if connection vendor oracle or dbdefault the single quotation mark is properly quoted and is set for new rows on oracle however it is not set on existing rows skip the assertion as it s probably a bug in oracle self assertequaloldpony specialchar dbdefault finally with connection schemaeditor as editor operation databasebackwards applabel editor newstate projectstate skipunlessdbfeaturesupportsexpressiondefaults def testaddfielddatabasedefaultfunctionself applabel testadflddf tablename fapplabelpony projectstate self setuptestmodelapplabel operation migrations addfield pony height models floatfielddbdefaultpi newstate projectstate clone operation stateforwardsapplabel newstate self assertequallennewstate modelsapplabel pony fields 6 field newstate modelsapplabel pony fieldsheight self assertequalfield default models notprovided self assertequalfield dbdefault pi projectstate apps getmodelapplabel pony objects createweight4 self assertcolumnnotexiststablename height add field with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertcolumnexiststablename height newmodel newstate apps getmodelapplabel pony oldpony newmodel objects get self assertalmostequaloldpony height math pi newpony newmodel objects createweight5 if not connection features canreturncolumnsfrominsert newpony refreshfromdb self assertalmostequaloldpony height math pi def testaddfieldbothdefaultsself add field reversal deconstruction tests the addfield operation with a manytomanyfield test the state alteration test the database alteration make sure the m2m field actually works and test reversal ensure the new field actually works and test reversal tests the removefield operation test the state alteration test the database alteration and test reversal and deconstruction tests the removefield operation on a foreign key tests the altermodeltable operation test the state alteration test the database alteration and test reversal and deconstruction tests the altermodeltable operation if the table name is set to none tests the altermodeltable operation if the table name is not changed test the state alteration test the database alteration and test reversal altermodeltable should rename autogenerated m2m tables add the m2m field rename the pony dbtable which should also rename the m2m table and test reversal add the m2m field point the m2m field to self reversal tests the alterfield operation test the state alteration test the database alteration and test reversal and deconstruction alter field reversal deconstruction the alterfield operation changing default to dbdefault applabel testalflcdtdd projectstate self setuptestmodelapplabel operation migrations alterfield pony pink models integerfielddbdefault4 newstate projectstate clone operation stateforwardsapplabel newstate oldpink projectstate modelsapplabel pony fieldspink self assertequaloldpink default 3 self assertisoldpink dbdefault models notprovided newpink newstate modelsapplabel pony fieldspink self assertisnewpink default models notprovided self assertequalnewpink dbdefault value4 pony projectstate apps getmodelapplabel pony objects createweight1 self assertequalpony pink 3 alter field with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate pony newstate apps getmodelapplabel pony objects createweight1 if not connection features canreturncolumnsfrominsert pony refreshfromdb self assertequalpony pink 4 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate pony projectstate apps getmodelapplabel pony objects createweight1 self assertequalpony pink 3 def testalterfieldchangenullabletodatabasedefaultnotnullself applabel testalflcntddnn projectstate self setuptestmodelapplabel operation migrations alterfield pony green models integerfielddbdefault4 newstate projectstate clone operation stateforwardsapplabel newstate oldgreen projectstate modelsapplabel pony fieldsgreen self assertisoldgreen dbdefault models notprovided newgreen newstate modelsapplabel pony fieldsgreen self assertequalnewgreen dbdefault value4 oldpony projectstate apps getmodelapplabel pony objects create weight1 self assertisnoneoldpony green alter field with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate oldpony refreshfromdb self assertequaloldpony green 4 pony newstate apps getmodelapplabel pony objects createweight1 if not connection features canreturncolumnsfrominsert pony refreshfromdb self assertequalpony green 4 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate pony projectstate apps getmodelapplabel pony objects createweight1 self assertisnonepony green def testalterfieldchangenullabletodecimaldatabasedefaultnotnullself applabel testalflcntdddn projectstate self setuptestmodelapplabel operation1 migrations addfield pony height models decimalfieldnulltrue maxdigits5 decimalplaces2 operation2 migrations alterfield pony height models decimalfield maxdigits5 decimalplaces2 dbdefaultdecimal12 22 tablename fapplabelpony self assertcolumnnotexiststablename height add field newstate projectstate clone operation1 stateforwardsapplabel newstate with connection schemaeditor as editor operation1 databaseforwardsapplabel editor projectstate newstate self assertcolumnexiststablename height oldpony newstate apps getmodelapplabel pony objects createweight1 self assertisnoneoldpony height alter field projectstate newstate newstate newstate clone operation2 stateforwardsapplabel newstate with connection schemaeditor as editor operation2 databaseforwardsapplabel editor projectstate newstate oldpony refreshfromdb self assertequaloldpony height decimal12 22 pony newstate apps getmodelapplabel pony objects createweight2 if not connection features canreturncolumnsfrominsert pony refreshfromdb self assertequalpony height decimal12 22 skipifdbfeatureinterpretsemptystringsasnulls def testalterfieldchangeblanknullabledatabasedefaulttonotnullself applabel testalflcbnddnn tablename fapplabelpony projectstate self setuptestmodelapplabel default yellow operation migrations alterfield pony yellow models charfieldblanktrue dbdefaultdefault maxlength20 newstate projectstate clone operation stateforwardsapplabel newstate self assertcolumnnulltablename yellow pony projectstate apps getmodelapplabel pony objects create weight1 yellownone self assertisnonepony yellow alter field with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertcolumnnotnulltablename yellow pony refreshfromdb self assertequalpony yellow default pony newstate apps getmodelapplabel pony objects createweight1 if not connection features canreturncolumnsfrominsert pony refreshfromdb self assertequalpony yellow default reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self assertcolumnnulltablename yellow pony projectstate apps getmodelapplabel pony objects create weight1 yellownone self assertisnonepony yellow def testalterfieldadddbcolumnnoopself applabel testafadbn projectstate self setuptestmodelapplabel relatedmodeltrue ponytable spony applabel newstate projectstate clone operation migrations alterfield pony weight models floatfielddbcolumnweight operation stateforwardsapplabel newstate self assertisnone projectstate modelsapplabel pony fieldsweight dbcolumn self assertequal newstate modelsapplabel pony fieldsweight dbcolumn weight self assertcolumnexistsponytable weight with connection schemaeditor as editor with self assertnumqueries0 operation databaseforwardsapplabel editor projectstate newstate self assertcolumnexistsponytable weight with connection schemaeditor as editor with self assertnumqueries0 operation databasebackwards applabel editor newstate projectstate self assertcolumnexistsponytable weight ridertable srider applabel newstate projectstate clone operation migrations alterfield rider pony models foreignkeypony models cascade dbcolumnponyid operation stateforwardsapplabel newstate self assertisnone projectstate modelsapplabel rider fieldspony dbcolumn self assertis newstate modelsapplabel rider fieldspony dbcolumn ponyid self assertcolumnexistsridertable ponyid with connection schemaeditor as editor with self assertnumqueries0 operation databaseforwardsapplabel editor projectstate newstate self assertcolumnexistsridertable ponyid with connection schemaeditor as editor with self assertnumqueries0 operation databaseforwardsapplabel editor newstate projectstate self assertcolumnexistsridertable ponyid def testalterfieldforeignobjectnoopself applabel testalflfonoop projectstate self setuptestmodelapplabel projectstate self applyoperations applabel projectstate migrations createmodel rider fields ponyid models integerfield pony models foreignobject fapplabel pony models cascade fromfieldsponyid tofieldsid operation migrations alterfield rider pony models foreignobject fapplabel pony models cascade fromfieldsponyid tofieldsid nulltrue newstate projectstate clone operation stateforwardsapplabel newstate with capturequeriescontextconnection as ctx connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertis anyalter in querysql for query in ctx capturedqueries false skipunlessdbfeaturesupportscomments def testaltermodeltablecommentself applabel testalmotaco projectstate self setuptestmodelapplabel ponytable fapplabelpony add table comment operation migrations altermodeltablecommentpony custom pony comment self assertequaloperation describe alter pony table comment self assertequaloperation migrationnamefragment alterponytablecomment newstate projectstate clone operation stateforwardsapplabel newstate self assertequal newstate modelsapplabel pony optionsdbtablecomment custom pony comment self asserttablecommentnotexistsponytable with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self asserttablecommentponytable custom pony comment reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self asserttablecommentnotexistsponytable deconstruction definition operation deconstruct self assertequaldefinition0 altermodeltablecomment self assertequaldefinition1 self assertequal definition2 name pony tablecomment custom pony comment def testalterfieldpkself projectstate self setuptestmodeltestalflpk test the state alteration operation migrations alterfield pony id models integerfieldprimarykeytrue newstate projectstate clone operation stateforwardstestalflpk newstate self assertisinstance projectstate modelstestalflpk pony fieldsid models autofield self assertisinstance newstate modelstestalflpk pony fieldsid models integerfield test the database alteration with connection schemaeditor as editor operation databaseforwardstestalflpk editor projectstate newstate and test reversal with connection schemaeditor as editor operation databasebackwards testalflpk editor newstate projectstate skipunlessdbfeaturesupportsforeignkeys def testalterfieldpkfkself projectstate self setuptestmodeltestalflpkfk relatedmodeltrue projectstate self applyoperations testalflpkfk projectstate migrations createmodel stable fields ponies models manytomanyfieldpony migrations addfield pony stables models manytomanyfieldstable test the state alteration operation migrations alterfield pony id models floatfieldprimarykeytrue newstate projectstate clone operation stateforwardstestalflpkfk newstate self assertisinstance projectstate modelstestalflpkfk pony fieldsid models autofield self assertisinstance newstate modelstestalflpkfk pony fieldsid models floatfield def assertidtypeequalsfktype with connection cursor as cursor idtype idnull c typecode c nullok for c in connection introspection gettabledescription cursor testalflpkfkpony if c name id 0 fktype fknull c typecode c nullok for c in connection introspection gettabledescription cursor testalflpkfkrider if c name ponyid 0 m2mfktype m2mfknull c typecode c nullok for c in connection introspection gettabledescription cursor testalflpkfkponystables if c name ponyid 0 remotem2mfktype remotem2mfknull c typecode c nullok for c in connection introspection gettabledescription cursor testalflpkfkstableponies if c name ponyid 0 self assertequalidtype fktype self assertequalidtype m2mfktype self assertequalidtype remotem2mfktype self assertequalidnull fknull self assertequalidnull m2mfknull self assertequalidnull remotem2mfknull assertidtypeequalsfktype test the database alteration with connection schemaeditor as editor operation databaseforwards testalflpkfk editor projectstate newstate assertidtypeequalsfktype if connection features supportsforeignkeys self assertfkexists testalflpkfkponystables ponyid testalflpkfkpony id self assertfkexists testalflpkfkstableponies ponyid testalflpkfkpony id and test reversal with connection schemaeditor as editor operation databasebackwards testalflpkfk editor newstate projectstate assertidtypeequalsfktype if connection features supportsforeignkeys self assertfkexists testalflpkfkponystables ponyid testalflpkfkpony id self assertfkexists testalflpkfkstableponies ponyid testalflpkfkpony id skipunlessdbfeaturesupportscollationoncharfield supportsforeignkeys def testalterfieldpkfkdbcollationself collation connection features testcollations getnondefault if not collation self skiptestlanguage collations are not supported applabel testalflpkfkdbc projectstate self applyoperations applabel projectstate migrations createmodel pony id models charfieldprimarykeytrue maxlength10 migrations createmodel rider pony models foreignkeypony models cascade migrations createmodel stable ponies models manytomanyfieldpony state alteration operation migrations alterfield pony id models charfield primarykeytrue maxlength10 dbcollationcollation newstate projectstate clone operation stateforwardsapplabel newstate database alteration with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertcolumncollationfapplabelpony id collation self assertcolumncollationfapplabelrider ponyid collation self assertcolumncollationfapplabelstableponies ponyid collation reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate def testalterfieldpkmtifkself applabel testalflpkmtifk projectstate self setuptestmodelapplabel mtimodeltrue projectstate self applyoperations applabel projectstate migrations createmodel shetlandrider fields pony models foreignkey fapplabel shetlandpony models cascade operation migrations alterfield pony id models bigautofieldprimarykeytrue newstate projectstate clone operation stateforwardsapplabel newstate self assertisinstance newstate modelsapplabel pony fieldsid models bigautofield def getcolumnidtypecursor table column return c typecode for c in connection introspection gettabledescription cursor fapplabeltable if c name column 0 def assertidtypeequalsmtifktype with connection cursor as cursor parentidtype getcolumnidtypecursor pony id childidtype getcolumnidtype cursor shetlandpony ponyptrid mtiidtype getcolumnidtypecursor shetlandrider ponyid self assertequalparentidtype childidtype self assertequalparentidtype mtiidtype assertidtypeequalsmtifktype alter primary key with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate assertidtypeequalsmtifktype if connection features supportsforeignkeys self assertfkexists fapplabelshetlandpony ponyptrid fapplabelpony id self assertfkexists fapplabelshetlandrider ponyid fapplabelshetlandpony ponyptrid reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate assertidtypeequalsmtifktype if connection features supportsforeignkeys self assertfkexists fapplabelshetlandpony ponyptrid fapplabelpony id self assertfkexists fapplabelshetlandrider ponyid fapplabelshetlandpony ponyptrid def testalterfieldpkmtiandfktobaseself applabel testalflpkmtiftb projectstate self setuptestmodel applabel mtimodeltrue relatedmodeltrue operation migrations alterfield pony id models bigautofieldprimarykeytrue newstate projectstate clone operation stateforwardsapplabel newstate self assertisinstance newstate modelsapplabel pony fieldsid models bigautofield def getcolumnidtypecursor table column return c typecode for c in connection introspection gettabledescription cursor fapplabeltable if c name column 0 def assertidtypeequalsmtifktype with connection cursor as cursor parentidtype getcolumnidtypecursor pony id fkidtype getcolumnidtypecursor rider ponyid childidtype getcolumnidtype cursor shetlandpony ponyptrid self assertequalparentidtype childidtype self assertequalparentidtype fkidtype assertidtypeequalsmtifktype alter primary key with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate assertidtypeequalsmtifktype if connection features supportsforeignkeys self assertfkexists fapplabelshetlandpony ponyptrid fapplabelpony id self assertfkexists fapplabelrider ponyid fapplabelpony id reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate assertidtypeequalsmtifktype if connection features supportsforeignkeys self assertfkexists fapplabelshetlandpony ponyptrid fapplabelpony id self assertfkexists fapplabelrider ponyid fapplabelpony id skipunlessdbfeaturesupportsforeignkeys def testalterfieldreloadsstateonfkwithtofieldtargettypechangeself applabel testalflrsfkwtflttc projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue code models integerfielduniquetrue migrations createmodel pony fields id models autofieldprimarykeytrue rider models foreignkey s rider applabel models cascade tofieldcode operation migrations alterfield rider code models charfieldmaxlength100 uniquetrue self applyoperationsapplabel projectstate operationsoperation idtype idnull c typecode c nullok for c in self gettabledescriptionsrider applabel if c name code 0 fktype fknull c typecode c nullok for c in self gettabledescriptionspony applabel if c name riderid 0 self assertequalidtype fktype self assertequalidnull fknull skipunlessdbfeaturesupportsforeignkeys def testalterfieldreloadsstatefkwithtofieldrelatednametargettypechange self applabel testalflrsfkwtflrnttc projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models autofieldprimarykeytrue code models positiveintegerfielduniquetrue migrations createmodel pony fields id models autofieldprimarykeytrue rider models foreignkey s rider applabel models cascade tofieldcode relatedname operation migrations alterfield rider code models charfieldmaxlength100 uniquetrue self applyoperationsapplabel projectstate operationsoperation def testalterfieldreloadsstateonfktargetchangesself applabel alteralterfieldreloadsstateonfktargetchanges projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models charfieldprimarykeytrue maxlength100 migrations createmodel pony fields id models charfieldprimarykeytrue maxlength100 rider models foreignkeys rider applabel models cascade migrations createmodel ponyrider fields id models autofieldprimarykeytrue pony models foreignkeys pony applabel models cascade projectstate self applyoperations applabel projectstate operations migrations alterfield rider id models charfieldprimarykeytrue maxlength99 migrations alterfield pony id models charfieldprimarykeytrue maxlength99 def testalterfieldreloadsstateonfkwithtofieldtargetchangesself applabel alteralterfieldreloadsstateonfkwithtofieldtargetchanges projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models charfieldprimarykeytrue maxlength100 slug models charfielduniquetrue maxlength100 migrations createmodel pony fields id models charfieldprimarykeytrue maxlength100 rider models foreignkey s rider applabel models cascade tofieldslug slug models charfielduniquetrue maxlength100 migrations createmodel ponyrider fields id models autofieldprimarykeytrue pony models foreignkey s pony applabel models cascade tofieldslug projectstate self applyoperations applabel projectstate operations migrations alterfield rider slug models charfielduniquetrue maxlength99 migrations alterfield pony slug models charfielduniquetrue maxlength99 def testalterfieldpkfkchartointself applabel alterfieldpkfkchartoint projectstate self applyoperations applabel projectstate operations migrations createmodel nameparent fields id models charfieldmaxlength255 primarykeytrue migrations createmodel namechild fields id models bigautofieldprimarykeytrue parent models foreignkey fapplabel parent ondeletemodels cascade self applyoperations applabel projectstate operations migrations alterfield modelnameparent nameid fieldmodels bigintegerfieldprimarykeytrue def testrenamefieldreloadsstateonfktargetchangesself applabel alterrenamefieldreloadsstateonfktargetchanges projectstate self applyoperations applabel projectstate operations migrations createmodel rider fields id models charfieldprimarykeytrue maxlength100 migrations createmodel pony fields id models charfieldprimarykeytrue maxlength100 rider models foreignkeys rider applabel models cascade migrations createmodel ponyrider fields id models autofieldprimarykeytrue pony models foreignkeys pony applabel models cascade projectstate self applyoperations applabel projectstate operations migrations renamefieldrider id id2 migrations alterfield pony id models charfieldprimarykeytrue maxlength99 def testrenamefieldself projectstate self setuptestmodeltestrnfl operation migrations renamefieldpony pink blue self assertequaloperation describe rename field pink on pony to blue self assertequaloperation migrationnamefragment renamepinkponyblue newstate projectstate clone operation stateforwardstestrnfl newstate self assertinblue newstate modelstestrnfl pony fields self assertnotinpink newstate modelstestrnfl pony fields rename field self assertcolumnexiststestrnflpony pink self assertcolumnnotexiststestrnflpony blue with connection schemaeditor as editor operation databaseforwardstestrnfl editor projectstate newstate self assertcolumnexiststestrnflpony blue self assertcolumnnotexiststestrnflpony pink reversal with connection schemaeditor as editor operation databasebackwardstestrnfl editor newstate projectstate self assertcolumnexiststestrnflpony pink self assertcolumnnotexiststestrnflpony blue deconstruction definition operation deconstruct self assertequaldefinition0 renamefield self assertequaldefinition1 self assertequal definition2 modelname pony oldname pink newname blue def testrenamefielduniquetogetherself projectstate self setuptestmodeltestrnflut uniquetogethertrue operation migrations renamefieldpony pink blue newstate projectstate clone operation stateforwardstestrnflut newstate uniquetogether has the renamed column self assertin blue newstate modelstestrnflut pony optionsuniquetogether0 self assertnotin pink newstate modelstestrnflut pony optionsuniquetogether0 rename field self assertcolumnexiststestrnflutpony pink self assertcolumnnotexiststestrnflutpony blue with connection schemaeditor as editor operation databaseforwardstestrnflut editor projectstate newstate self assertcolumnexiststestrnflutpony blue self assertcolumnnotexiststestrnflutpony pink the unique constraint has been ported over with connection cursor as cursor cursor executeinsert into testrnflutpony blue weight values 1 1 with self assertraisesintegrityerror with atomic cursor execute insert into testrnflutpony blue weight values 1 1 cursor executedelete from testrnflutpony reversal with connection schemaeditor as editor operation databasebackwards testrnflut editor newstate projectstate self assertcolumnexiststestrnflutpony pink self assertcolumnnotexiststestrnflutpony blue def testrenamefieldwithdbcolumnself projectstate self applyoperations testrfwdbc projectstate operations migrations createmodel pony fields id models autofieldprimarykeytrue field models integerfielddbcolumndbfield fkfield models foreignkey pony models cascade dbcolumndbfkfield newstate projectstate clone operation migrations renamefieldpony field renamedfield operation stateforwardstestrfwdbc newstate self assertinrenamedfield newstate modelstestrfwdbc pony fields self assertnotinfield newstate modelstestrfwdbc pony fields self assertcolumnexiststestrfwdbcpony dbfield with connection schemaeditor as editor with self assertnumqueries0 operation databaseforwards testrfwdbc editor projectstate newstate self assertcolumnexiststestrfwdbcpony dbfield with connection schemaeditor as editor with self assertnumqueries0 operation databasebackwards testrfwdbc editor newstate projectstate self assertcolumnexiststestrfwdbcpony dbfield newstate projectstate clone operation migrations renamefieldpony fkfield renamedfkfield operation stateforwardstestrfwdbc newstate self assertin renamedfkfield newstate modelstestrfwdbc pony fields self assertnotinfkfield newstate modelstestrfwdbc pony fields self assertcolumnexiststestrfwdbcpony dbfkfield with connection schemaeditor as editor with self assertnumqueries0 operation databaseforwards testrfwdbc editor projectstate newstate self assertcolumnexiststestrfwdbcpony dbfkfield with connection schemaeditor as editor with self assertnumqueries0 operation databasebackwards testrfwdbc editor newstate projectstate self assertcolumnexiststestrfwdbcpony dbfkfield def testrenamefieldcaseself projectstate self applyoperations testrfmx projectstate operations migrations createmodel pony fields id models autofieldprimarykeytrue field models integerfield newstate projectstate clone operation migrations renamefieldpony field field operation stateforwardstestrfmx newstate self assertinfield newstate modelstestrfmx pony fields self assertcolumnexiststestrfmxpony field with connection schemaeditor as editor operation databaseforwardstestrfmx editor projectstate newstate self assertcolumnexists testrfmxpony connection introspection identifierconverterfield with connection schemaeditor as editor operation databasebackwardstestrfmx editor newstate projectstate self assertcolumnexiststestrfmxpony field def testrenamemissingfieldself state projectstate state addmodelmodelstateapp model with self assertraisesmessage fielddoesnotexist app model has no field named field migrations renamefieldmodel field newfield stateforwards app state def testrenamereferencedfieldstateforwardself state projectstate state addmodel modelstate app model id models autofieldprimarykeytrue field models integerfielduniquetrue state addmodel modelstate app othermodel id models autofieldprimarykeytrue fk models foreignkeymodel models cascade tofieldfield fo models foreignobject model models cascade fromfieldsfk tofieldsfield operation migrations renamefieldmodel field renamed newstate state clone operation stateforwardsapp newstate self assertequal newstate modelsapp othermodel fieldsfk remotefield fieldname renamed self assertequal newstate modelsapp othermodel fieldsfk fromfields self self assertequal newstate modelsapp othermodel fieldsfk tofields renamed self assertequal newstate modelsapp othermodel fieldsfo fromfields fk self assertequal newstate modelsapp othermodel fieldsfo tofields renamed operation migrations renamefieldothermodel fk renamedfk newstate state clone operation stateforwardsapp newstate self assertequal newstate modelsapp othermodel fieldsrenamedfk remotefield fieldname renamed self assertequal newstate modelsapp othermodel fieldsrenamedfk fromfields self self assertequal newstate modelsapp othermodel fieldsrenamedfk tofields renamed self assertequal newstate modelsapp othermodel fieldsfo fromfields renamedfk self assertequal newstate modelsapp othermodel fieldsfo tofields renamed def testalteruniquetogetherself projectstate self setuptestmodeltestalunto test the state alteration operation migrations alteruniquetogetherpony pink weight self assertequal operation describe alter uniquetogether for pony 1 constraints self assertequal operation migrationnamefragment alterponyuniquetogether newstate projectstate clone operation stateforwardstestalunto newstate self assertequal len projectstate modelstestalunto pony options get uniquetogether set 0 self assertequal len newstate modelstestalunto pony options get uniquetogether set 1 make sure we can insert duplicate rows with connection cursor as cursor cursor executeinsert into testaluntopony pink weight values 1 1 cursor executeinsert into testaluntopony pink weight values 1 1 cursor executedelete from testaluntopony test the database alteration with connection schemaeditor as editor operation databaseforwards testalunto editor projectstate newstate cursor executeinsert into testaluntopony pink weight values 1 1 with self assertraisesintegrityerror with atomic cursor execute insert into testaluntopony pink weight values 1 1 cursor executedelete from testaluntopony and test reversal with connection schemaeditor as editor operation databasebackwards testalunto editor newstate projectstate cursor executeinsert into testaluntopony pink weight values 1 1 cursor executeinsert into testaluntopony pink weight values 1 1 cursor executedelete from testaluntopony test flat uniquetogether operation migrations alteruniquetogetherpony pink weight operation stateforwardstestalunto newstate self assertequal len newstate modelstestalunto pony options get uniquetogether set 1 and deconstruction definition operation deconstruct self assertequaldefinition0 alteruniquetogether self assertequaldefinition1 self assertequal definition2 name pony uniquetogether pink weight def testalteruniquetogetherremoveself operation migrations alteruniquetogetherpony none self assertequal operation describe alter uniquetogether for pony 0 constraints skipunlessdbfeatureallowsmultipleconstraintsonsamefields def testremoveuniquetogetheronpkfieldself applabel testrutopkf projectstate self applyoperations applabel projectstate operations migrations createmodel pony fieldsid models autofieldprimarykeytrue optionsuniquetogether id tablename fapplabelpony pkconstraintname ftablenamepkey uniquetogetherconstraintname ftablenameidfb61f881uniq self assertconstraintexiststablename pkconstraintname valuefalse self assertconstraintexists tablename uniquetogetherconstraintname valuefalse newstate projectstate clone operation migrations alteruniquetogetherpony set operation stateforwardsapplabel newstate with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertconstraintexiststablename pkconstraintname valuefalse self assertconstraintnotexiststablename uniquetogetherconstraintname skipunlessdbfeatureallowsmultipleconstraintsonsamefields def testremoveuniquetogetheronuniquefieldself applabel testrutouf projectstate self applyoperations applabel projectstate operations migrations createmodel pony fields id models autofieldprimarykeytrue name models charfieldmaxlength30 uniquetrue optionsuniquetogether name tablename fapplabelpony uniqueconstraintname ftablenamenamekey uniquetogetherconstraintname ftablenamename694f3b9funiq self assertconstraintexiststablename uniqueconstraintname valuefalse self assertconstraintexists tablename uniquetogetherconstraintname valuefalse newstate projectstate clone operation migrations alteruniquetogetherpony set operation stateforwardsapplabel newstate with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertconstraintexiststablename uniqueconstraintname valuefalse self assertconstraintnotexiststablename uniquetogetherconstraintname def testaddindexself projectstate self setuptestmodeltestadin msg indexes passed to addindex operations require a name argument index fields pink doesn t have one with self assertraisesmessagevalueerror msg migrations addindexpony models indexfieldspink index models indexfieldspink nametestadinponypinkidx operation migrations addindexpony index self assertequal operation describe create index testadinponypinkidx on fields pink of model pony self assertequal operation migrationnamefragment ponytestadinponypinkidx newstate projectstate clone operation stateforwardstestadin newstate test the database alteration self assertequal lennewstate modelstestadin pony optionsindexes 1 self assertindexnotexiststestadinpony pink with connection schemaeditor as editor operation databaseforwardstestadin editor projectstate newstate self assertindexexiststestadinpony pink and test reversal with connection schemaeditor as editor operation databasebackwardstestadin editor newstate projectstate self assertindexnotexiststestadinpony pink and deconstruction definition operation deconstruct self assertequaldefinition0 addindex self assertequaldefinition1 self assertequaldefinition2 modelname pony index index def testremoveindexself projectstate self setuptestmodeltestrmin multicolindextrue self asserttableexiststestrminpony self assertindexexiststestrminpony pink weight operation migrations removeindexpony ponytestidx self assertequaloperation describe remove index ponytestidx from pony self assertequal operation migrationnamefragment removeponyponytestidx newstate projectstate clone operation stateforwardstestrmin newstate test the state alteration self assertequal lennewstate modelstestrmin pony optionsindexes 0 self assertindexexiststestrminpony pink weight test the database alteration with connection schemaeditor as editor operation databaseforwardstestrmin editor projectstate newstate self assertindexnotexiststestrminpony pink weight and test reversal with connection schemaeditor as editor operation databasebackwardstestrmin editor newstate projectstate self assertindexexiststestrminpony pink weight and deconstruction definition operation deconstruct self assertequaldefinition0 removeindex self assertequaldefinition1 self assertequaldefinition2 modelname pony name ponytestidx also test a field dropped with index sqlite remake issue operations migrations removeindexpony ponytestidx migrations removefieldpony pink self assertcolumnexiststestrminpony pink self assertindexexiststestrminpony pink weight test database alteration newstate projectstate clone self applyoperationstestrmin newstate operationsoperations self assertcolumnnotexiststestrminpony pink self assertindexnotexiststestrminpony pink weight and test reversal self unapplyoperationstestrmin projectstate operationsoperations self assertindexexiststestrminpony pink weight def testrenameindexself applabel testrnin projectstate self setuptestmodelapplabel indextrue tablename applabel pony self assertindexnameexiststablename ponypinkidx self assertindexnamenotexiststablename newponytestidx operation migrations renameindex pony newnamenewponytestidx oldnameponypinkidx self assertequal operation describe rename index ponypinkidx on pony to newponytestidx self assertequal operation migrationnamefragment renameponypinkidxnewponytestidx newstate projectstate clone operation stateforwardsapplabel newstate rename index expectedqueries 1 if connection features canrenameindex else 2 with connection schemaeditor as editor self assertnumqueries expectedqueries operation databaseforwardsapplabel editor projectstate newstate self assertindexnamenotexiststablename ponypinkidx self assertindexnameexiststablename newponytestidx reversal with connection schemaeditor as editor self assertnumqueries expectedqueries operation databasebackwardsapplabel editor newstate projectstate self assertindexnameexiststablename ponypinkidx self assertindexnamenotexiststablename newponytestidx deconstruction definition operation deconstruct self assertequaldefinition0 renameindex self assertequaldefinition1 self assertequal definition2 modelname pony oldname ponypinkidx newname newponytestidx def testrenameindexargumentsself msg renameindex oldname and oldfields are mutually exclusive with self assertraisesmessagevalueerror msg migrations renameindex pony newnamenewidxname oldnameoldidxname oldfieldsweight pink msg renameindex requires one of oldname and oldfields arguments to be set with self assertraisesmessagevalueerror msg migrations renameindexpony newnamenewidxname def testrenameindexunknownunnamedindexself applabel testrninuui projectstate self setuptestmodelapplabel operation migrations renameindex pony newnamenewponytestidx oldfieldsweight pink newstate projectstate clone operation stateforwardsapplabel newstate msg found wrong number 0 of indexes for testrninuuiponyweight pink with connection schemaeditor as editor with self assertraisesmessagevalueerror msg operation databaseforwardsapplabel editor projectstate newstate def testaddindexstateforwardsself projectstate self setuptestmodeltestadinsf index models indexfieldspink nametestadinsfponypinkidx oldmodel projectstate apps getmodeltestadinsf pony newstate projectstate clone operation migrations addindexpony index operation stateforwardstestadinsf newstate newmodel newstate apps getmodeltestadinsf pony self assertisnotoldmodel newmodel def testremoveindexstateforwardsself projectstate self setuptestmodeltestrminsf index models indexfieldspink nametestrminsfponypinkidx migrations addindexpony index stateforwardstestrminsf projectstate oldmodel projectstate apps getmodeltestrminsf pony newstate projectstate clone operation migrations removeindexpony testrminsfponypinkidx operation stateforwardstestrminsf newstate newmodel newstate apps getmodeltestrminsf pony self assertisnotoldmodel newmodel def testrenameindexstateforwardsself applabel testrnidsf projectstate self setuptestmodelapplabel indextrue oldmodel projectstate apps getmodelapplabel pony newstate projectstate clone operation migrations renameindex pony newnamenewponypinkidx oldnameponypinkidx operation stateforwardsapplabel newstate newmodel newstate apps getmodelapplabel pony self assertisnotoldmodel newmodel self assertequalnewmodel meta indexes0 name newponypinkidx skipunlessdbfeaturesupportsexpressionindexes def testaddfuncindexself applabel testaddfuncin indexname fapplabelponyabsidx tablename fapplabelpony projectstate self setuptestmodelapplabel index models indexabsweight nameindexname operation migrations addindexpony index self assertequal operation describe create index testaddfuncinponyabsidx on absfweight on model pony self assertequal operation migrationnamefragment ponytestaddfuncinponyabsidx newstate projectstate clone operation stateforwardsapplabel newstate self assertequallennewstate modelsapplabel pony optionsindexes 1 self assertindexnamenotexiststablename indexname add index with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertindexnameexiststablename indexname reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self assertindexnamenotexiststablename indexname deconstruction definition operation deconstruct self assertequaldefinition0 addindex self assertequaldefinition1 self assertequaldefinition2 modelname pony index index skipunlessdbfeaturesupportsexpressionindexes def testremovefuncindexself applabel testrmfuncin indexname fapplabelponyabsidx tablename fapplabelpony projectstate self setuptestmodel applabel indexes models indexabsweight nameindexname self asserttableexiststablename self assertindexnameexiststablename indexname operation migrations removeindexpony indexname self assertequal operation describe remove index testrmfuncinponyabsidx from pony self assertequal operation migrationnamefragment removeponytestrmfuncinponyabsidx newstate projectstate clone operation stateforwardsapplabel newstate self assertequallennewstate modelsapplabel pony optionsindexes 0 remove index with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertindexnamenotexiststablename indexname reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self assertindexnameexiststablename indexname deconstruction definition operation deconstruct self assertequaldefinition0 removeindex self assertequaldefinition1 self assertequaldefinition2 modelname pony name indexname skipunlessdbfeaturesupportsexpressionindexes def testalterfieldwithfuncindexself applabel testalfuncin indexname fapplabelponyidx tablename fapplabelpony projectstate self setuptestmodel applabel indexesmodels indexabspink nameindexname operation migrations alterfield pony pink models integerfieldnulltrue newstate projectstate clone operation stateforwardsapplabel newstate with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertindexnameexiststablename indexname with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self assertindexnameexiststablename indexname def testalterfieldwithindexself projectstate self setuptestmodeltestalflin indextrue operation migrations alterfield pony pink models integerfieldnulltrue newstate projectstate clone operation stateforwardstestalflin newstate test the database alteration self assertcolumnnotnulltestalflinpony pink with connection schemaeditor as editor operation databaseforwardstestalflin editor projectstate newstate index hasn t been dropped self assertindexexiststestalflinpony pink and test reversal with connection schemaeditor as editor operation databasebackwards testalflin editor newstate projectstate ensure the index is still there self assertindexexiststestalflinpony pink def testalterindextogetherremoveself operation migrations alterindextogetherpony none self assertequal operation describe alter indextogether for pony 0 constraints def testaddconstraintself projectstate self setuptestmodeltestaddconstraint gtcheck models qpinkgt2 gtconstraint models checkconstraint checkgtcheck nametestaddconstraintponypinkgt2 gtoperation migrations addconstraintpony gtconstraint self assertequal gtoperation describe create constraint testaddconstraintponypinkgt2 on model pony self assertequal gtoperation migrationnamefragment ponytestaddconstraintponypinkgt2 test the state alteration newstate projectstate clone gtoperation stateforwardstestaddconstraint newstate self assertequal lennewstate modelstestaddconstraint pony optionsconstraints 1 pony newstate apps getmodeltestaddconstraint pony self assertequallenpony meta constraints 1 test the database alteration with capturequeriescontextconnection as ctx connection schemaeditor as editor gtoperation databaseforwards testaddconstraint editor projectstate newstate if connection features supportstablecheckconstraints with self assertraisesintegrityerror transaction atomic pony objects createpink1 weight1 0 else self assertis anycheck in querysql for query in ctx capturedqueries false pony objects createpink1 weight1 0 add another one ltcheck models qpinklt100 ltconstraint models checkconstraint checkltcheck nametestaddconstraintponypinklt100 ltoperation migrations addconstraintpony ltconstraint ltoperation stateforwardstestaddconstraint newstate self assertequal lennewstate modelstestaddconstraint pony optionsconstraints 2 pony newstate apps getmodeltestaddconstraint pony self assertequallenpony meta constraints 2 with capturequeriescontextconnection as ctx connection schemaeditor as editor ltoperation databaseforwards testaddconstraint editor projectstate newstate if connection features supportstablecheckconstraints with self assertraisesintegrityerror transaction atomic pony objects createpink100 weight1 0 else self assertis anycheck in querysql for query in ctx capturedqueries false pony objects createpink100 weight1 0 test reversal with connection schemaeditor as editor gtoperation databasebackwards testaddconstraint editor newstate projectstate pony objects createpink1 weight1 0 test deconstruction definition gtoperation deconstruct self assertequaldefinition0 addconstraint self assertequaldefinition1 self assertequal definition2 modelname pony constraint gtconstraint skipunlessdbfeaturesupportstablecheckconstraints def testaddconstraintpercentescapingself applabel addconstraintstringquoting operations migrations createmodel fields id models autofieldprimarykeytrue name models charfieldmaxlength100 surname models charfieldmaxlength100 default rebate models charfieldmaxlength100 fromstate self applyoperationsapplabel projectstate operations checks generated in startswith lookup should be escaped in a way that is considered a leading wildcard models qnamestartswithalbert name alberta name artur literal should be escaped in a way that is not a considered a wildcard models qrebateendswith rebate 10 rebate 10 righthandside baked literals should not be used for parameters interpolation models qsurnamestartswithmodels fname name albert name albert surname alberto exact matches against literals should also be supported models qname name name albert for check valid invalid in checks with self subtestcheckcheck validvalid invalidinvalid constraint models checkconstraintcheckcheck nameconstraint operation migrations addconstraint constraint tostate fromstate clone operation stateforwardsapplabel tostate with connection schemaeditor as editor operation databaseforwardsapplabel editor fromstate tostate tostate apps getmodelapplabel try with transaction atomic objects createvalid delete with self assertraisesintegrityerror transaction atomic objects createinvalid finally with connection schemaeditor as editor operation databasebackwards applabel editor fromstate tostate skipunlessdbfeaturesupportstablecheckconstraints def testaddorconstraintself applabel testaddorconstraint constraintname addconstraintor fromstate self setuptestmodelapplabel check models qpinkgt2 weightgt2 models qweightlt0 constraint models checkconstraintcheckcheck nameconstraintname operation migrations addconstraintpony constraint tostate fromstate clone operation stateforwardsapplabel tostate with connection schemaeditor as editor operation databaseforwardsapplabel editor fromstate tostate pony tostate apps getmodelapplabel pony with self assertraisesintegrityerror transaction atomic pony objects createpink2 weight3 0 with self assertraisesintegrityerror transaction atomic pony objects createpink3 weight1 0 pony objects bulkcreate ponypink3 weight1 0 ponypink1 weight1 0 ponypink3 weight3 0 skipunlessdbfeaturesupportstablecheckconstraints def testaddconstraintcombinableself applabel testaddconstraintcombinable operations migrations createmodel book fields id models autofieldprimarykeytrue read models positiveintegerfield unread models positiveintegerfield fromstate self applyoperationsapplabel projectstate operations constraint models checkconstraint checkmodels qread100 models funread nametestaddconstraintcombinablesum100 operation migrations addconstraintbook constraint tostate fromstate clone operation stateforwardsapplabel tostate with connection schemaeditor as editor operation databaseforwardsapplabel editor fromstate tostate book tostate apps getmodelapplabel book with self assertraisesintegrityerror transaction atomic book objects createread70 unread10 book objects createread70 unread30 def testremoveconstraintself projectstate self setuptestmodel testremoveconstraint constraints models checkconstraint checkmodels qpinkgt2 nametestremoveconstraintponypinkgt2 models checkconstraint checkmodels qpinklt100 nametestremoveconstraintponypinklt100 gtoperation migrations removeconstraint pony testremoveconstraintponypinkgt2 self assertequal gtoperation describe remove constraint testremoveconstraintponypinkgt2 from model pony self assertequal gtoperation migrationnamefragment removeponytestremoveconstraintponypinkgt2 test state alteration newstate projectstate clone gtoperation stateforwardstestremoveconstraint newstate self assertequal len newstate modelstestremoveconstraint pony optionsconstraints 1 pony newstate apps getmodeltestremoveconstraint pony self assertequallenpony meta constraints 1 test database alteration with connection schemaeditor as editor gtoperation databaseforwards testremoveconstraint editor projectstate newstate pony objects createpink1 weight1 0 delete if connection features supportstablecheckconstraints with self assertraisesintegrityerror transaction atomic pony objects createpink100 weight1 0 else pony objects createpink100 weight1 0 remove the other one ltoperation migrations removeconstraint pony testremoveconstraintponypinklt100 ltoperation stateforwardstestremoveconstraint newstate self assertequal len newstate modelstestremoveconstraint pony optionsconstraints 0 pony newstate apps getmodeltestremoveconstraint pony self assertequallenpony meta constraints 0 with connection schemaeditor as editor ltoperation databaseforwards testremoveconstraint editor projectstate newstate pony objects createpink100 weight1 0 delete test reversal with connection schemaeditor as editor gtoperation databasebackwards testremoveconstraint editor newstate projectstate if connection features supportstablecheckconstraints with self assertraisesintegrityerror transaction atomic pony objects createpink1 weight1 0 else pony objects createpink1 weight1 0 test deconstruction definition gtoperation deconstruct self assertequaldefinition0 removeconstraint self assertequaldefinition1 self assertequal definition2 modelname pony name testremoveconstraintponypinkgt2 def testaddpartialuniqueconstraintself projectstate self setuptestmodeltestaddpartialuniqueconstraint partialuniqueconstraint models uniqueconstraint fieldspink conditionmodels qweightgt5 nametestconstraintponypinkforweightgt5uniq operation migrations addconstraintpony partialuniqueconstraint self assertequal operation describe create constraint testconstraintponypinkforweightgt5uniq on model pony test the state alteration newstate projectstate clone operation stateforwardstestaddpartialuniqueconstraint newstate self assertequal len newstate modelstestaddpartialuniqueconstraint pony options constraints 1 pony newstate apps getmodeltestaddpartialuniqueconstraint pony self assertequallenpony meta constraints 1 test the database alteration with connection schemaeditor as editor operation databaseforwards testaddpartialuniqueconstraint editor projectstate newstate test constraint works pony objects createpink1 weight4 0 pony objects createpink1 weight4 0 pony objects createpink1 weight6 0 if connection features supportspartialindexes with self assertraisesintegrityerror transaction atomic pony objects createpink1 weight7 0 else pony objects createpink1 weight7 0 test reversal with connection schemaeditor as editor operation databasebackwards testaddpartialuniqueconstraint editor newstate projectstate test constraint doesn t work pony objects createpink1 weight7 0 test deconstruction definition operation deconstruct self assertequaldefinition0 addconstraint self assertequaldefinition1 self assertequal definition2 modelname pony constraint partialuniqueconstraint def testremovepartialuniqueconstraintself projectstate self setuptestmodel testremovepartialuniqueconstraint constraints models uniqueconstraint fieldspink conditionmodels qweightgt5 nametestconstraintponypinkforweightgt5uniq gtoperation migrations removeconstraint pony testconstraintponypinkforweightgt5uniq self assertequal gtoperation describe remove constraint testconstraintponypinkforweightgt5uniq from model pony test state alteration newstate projectstate clone gtoperation stateforwardstestremovepartialuniqueconstraint newstate self assertequal len newstate modelstestremovepartialuniqueconstraint pony options constraints 0 pony newstate apps getmodeltestremovepartialuniqueconstraint pony self assertequallenpony meta constraints 0 test database alteration with connection schemaeditor as editor gtoperation databaseforwards testremovepartialuniqueconstraint editor projectstate newstate test constraint doesn t work pony objects createpink1 weight4 0 pony objects createpink1 weight4 0 pony objects createpink1 weight6 0 pony objects createpink1 weight7 0 delete test reversal with connection schemaeditor as editor gtoperation databasebackwards testremovepartialuniqueconstraint editor newstate projectstate test constraint works if connection features supportspartialindexes with self assertraisesintegrityerror transaction atomic pony objects createpink1 weight7 0 else pony objects createpink1 weight7 0 test deconstruction definition gtoperation deconstruct self assertequaldefinition0 removeconstraint self assertequaldefinition1 self assertequal definition2 modelname pony name testconstraintponypinkforweightgt5uniq def testadddeferreduniqueconstraintself applabel testadddeferreduc projectstate self setuptestmodelapplabel deferreduniqueconstraint models uniqueconstraint fieldspink namedeferredpinkconstraintadd deferrablemodels deferrable deferred operation migrations addconstraintpony deferreduniqueconstraint self assertequal operation describe create constraint deferredpinkconstraintadd on model pony add constraint newstate projectstate clone operation stateforwardsapplabel newstate self assertequal lennewstate modelsapplabel pony optionsconstraints 1 pony newstate apps getmodelapplabel pony self assertequallenpony meta constraints 1 with connection schemaeditor as editor capturequeriescontext connection as ctx operation databaseforwardsapplabel editor projectstate newstate pony objects createpink1 weight4 0 if connection features supportsdeferrableuniqueconstraints unique constraint is deferred with transaction atomic obj pony objects createpink1 weight4 0 obj pink 2 obj save constraint behavior can be changed with set constraints with self assertraisesintegrityerror with transaction atomic connection cursor as cursor quotedname connection ops quotename deferreduniqueconstraint name cursor executeset constraints s immediate quotedname obj pony objects createpink1 weight4 0 obj pink 3 obj save else self assertequallenctx 0 pony objects createpink1 weight4 0 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate constraint doesn t work pony objects createpink1 weight4 0 deconstruction definition operation deconstruct self assertequaldefinition0 addconstraint self assertequaldefinition1 self assertequal definition2 modelname pony constraint deferreduniqueconstraint def testremovedeferreduniqueconstraintself applabel testremovedeferreduc deferreduniqueconstraint models uniqueconstraint fieldspink namedeferredpinkconstraintrm deferrablemodels deferrable deferred projectstate self setuptestmodel applabel constraintsdeferreduniqueconstraint operation migrations removeconstraintpony deferreduniqueconstraint name self assertequal operation describe remove constraint deferredpinkconstraintrm from model pony remove constraint newstate projectstate clone operation stateforwardsapplabel newstate self assertequal lennewstate modelsapplabel pony optionsconstraints 0 pony newstate apps getmodelapplabel pony self assertequallenpony meta constraints 0 with connection schemaeditor as editor capturequeriescontext connection as ctx operation databaseforwardsapplabel editor projectstate newstate constraint doesn t work pony objects createpink1 weight4 0 pony objects createpink1 weight4 0 delete if not connection features supportsdeferrableuniqueconstraints self assertequallenctx 0 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate if connection features supportsdeferrableuniqueconstraints unique constraint is deferred with transaction atomic obj pony objects createpink1 weight4 0 obj pink 2 obj save constraint behavior can be changed with set constraints with self assertraisesintegrityerror with transaction atomic connection cursor as cursor quotedname connection ops quotename deferreduniqueconstraint name cursor executeset constraints s immediate quotedname obj pony objects createpink1 weight4 0 obj pink 3 obj save else pony objects createpink1 weight4 0 deconstruction definition operation deconstruct self assertequaldefinition0 removeconstraint self assertequaldefinition1 self assertequal definition2 modelname pony name deferredpinkconstraintrm def testaddcoveringuniqueconstraintself applabel testaddcoveringuc projectstate self setuptestmodelapplabel coveringuniqueconstraint models uniqueconstraint fieldspink namecoveringpinkconstraintadd includeweight operation migrations addconstraintpony coveringuniqueconstraint self assertequal operation describe create constraint coveringpinkconstraintadd on model pony add constraint newstate projectstate clone operation stateforwardsapplabel newstate self assertequal lennewstate modelsapplabel pony optionsconstraints 1 pony newstate apps getmodelapplabel pony self assertequallenpony meta constraints 1 with connection schemaeditor as editor capturequeriescontext connection as ctx operation databaseforwardsapplabel editor projectstate newstate pony objects createpink1 weight4 0 if connection features supportscoveringindexes with self assertraisesintegrityerror pony objects createpink1 weight4 0 else self assertequallenctx 0 pony objects createpink1 weight4 0 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate constraint doesn t work pony objects createpink1 weight4 0 deconstruction definition operation deconstruct self assertequaldefinition0 addconstraint self assertequaldefinition1 self assertequal definition2 modelname pony constraint coveringuniqueconstraint def testremovecoveringuniqueconstraintself applabel testremovecoveringuc coveringuniqueconstraint models uniqueconstraint fieldspink namecoveringpinkconstraintrm includeweight projectstate self setuptestmodel applabel constraintscoveringuniqueconstraint operation migrations removeconstraintpony coveringuniqueconstraint name self assertequal operation describe remove constraint coveringpinkconstraintrm from model pony remove constraint newstate projectstate clone operation stateforwardsapplabel newstate self assertequal lennewstate modelsapplabel pony optionsconstraints 0 pony newstate apps getmodelapplabel pony self assertequallenpony meta constraints 0 with connection schemaeditor as editor capturequeriescontext connection as ctx operation databaseforwardsapplabel editor projectstate newstate constraint doesn t work pony objects createpink1 weight4 0 pony objects createpink1 weight4 0 delete if not connection features supportscoveringindexes self assertequallenctx 0 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate if connection features supportscoveringindexes with self assertraisesintegrityerror pony objects createpink1 weight4 0 else pony objects createpink1 weight4 0 deconstruction definition operation deconstruct self assertequaldefinition0 removeconstraint self assertequaldefinition1 self assertequal definition2 modelname pony name coveringpinkconstraintrm def testalterfieldwithfuncuniqueconstraintself applabel testalfuncuc constraintname fapplabelponyuq tablename fapplabelpony projectstate self setuptestmodel applabel constraints models uniqueconstraintpink weight nameconstraintname operation migrations alterfield pony pink models integerfieldnulltrue newstate projectstate clone operation stateforwardsapplabel newstate with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate if connection features supportsexpressionindexes self assertindexnameexiststablename constraintname with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate if connection features supportsexpressionindexes self assertindexnameexiststablename constraintname def testaddfuncuniqueconstraintself applabel testadfuncuc constraintname fapplabelponyabsuq tablename fapplabelpony projectstate self setuptestmodelapplabel constraint models uniqueconstraintabsweight nameconstraintname operation migrations addconstraintpony constraint self assertequal operation describe create constraint testadfuncucponyabsuq on model pony self assertequal operation migrationnamefragment ponytestadfuncucponyabsuq newstate projectstate clone operation stateforwardsapplabel newstate self assertequal lennewstate modelsapplabel pony optionsconstraints 1 self assertindexnamenotexiststablename constraintname add constraint with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate pony newstate apps getmodelapplabel pony pony objects createweight4 0 if connection features supportsexpressionindexes self assertindexnameexiststablename constraintname with self assertraisesintegrityerror pony objects createweight4 0 else self assertindexnamenotexiststablename constraintname pony objects createweight4 0 reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate self assertindexnamenotexiststablename constraintname constraint doesn t work pony objects createweight4 0 deconstruction definition operation deconstruct self assertequaldefinition0 addconstraint self assertequaldefinition1 self assertequal definition2 modelname pony constraint constraint def testremovefuncuniqueconstraintself applabel testrmfuncuc constraintname fapplabelponyabsuq tablename fapplabelpony projectstate self setuptestmodel applabel constraints models uniqueconstraintabsweight nameconstraintname self asserttableexiststablename if connection features supportsexpressionindexes self assertindexnameexiststablename constraintname operation migrations removeconstraintpony constraintname self assertequal operation describe remove constraint testrmfuncucponyabsuq from model pony self assertequal operation migrationnamefragment removeponytestrmfuncucponyabsuq newstate projectstate clone operation stateforwardsapplabel newstate self assertequal lennewstate modelsapplabel pony optionsconstraints 0 pony newstate apps getmodelapplabel pony self assertequallenpony meta constraints 0 remove constraint with connection schemaeditor as editor operation databaseforwardsapplabel editor projectstate newstate self assertindexnamenotexiststablename constraintname constraint doesn t work pony objects createpink1 weight4 0 pony objects createpink1 weight4 0 delete reversal with connection schemaeditor as editor operation databasebackwardsapplabel editor newstate projectstate if connection features supportsexpressionindexes self assertindexnameexiststablename constraintname with self assertraisesintegrityerror pony objects createweight4 0 else self assertindexnamenotexiststablename constraintname pony objects createweight4 0 deconstruction definition operation deconstruct self assertequaldefinition0 removeconstraint self assertequaldefinition1 self assertequaldefinition2 modelname pony name constraintname def testaltermodeloptionsself projectstate self setuptestmodeltestalmoop test the state alteration no db alteration to test operation migrations altermodeloptions pony permissions cangroom can groom self assertequaloperation describe change meta options on pony self assertequaloperation migrationnamefragment alterponyoptions newstate projectstate clone operation stateforwardstestalmoop newstate self assertequal len projectstate modelstestalmoop pony options get permissions 0 self assertequal lennewstate modelstestalmoop pony options getpermissions 1 self assertequal newstate modelstestalmoop pony optionspermissions00 cangroom and deconstruction definition operation deconstruct self assertequaldefinition0 altermodeloptions self assertequaldefinition1 self assertequal definition2 name pony options permissions cangroom can groom def testaltermodeloptionsemptyingself projectstate self setuptestmodeltestalmoop optionstrue test the state alteration no db alteration to test operation migrations altermodeloptionspony self assertequaloperation describe change meta options on pony newstate projectstate clone operation stateforwardstestalmoop newstate self assertequal len projectstate modelstestalmoop pony options get permissions 1 self assertequal lennewstate modelstestalmoop pony options getpermissions 0 and deconstruction definition operation deconstruct self assertequaldefinition0 altermodeloptions self assertequaldefinition1 self assertequaldefinition2 name pony options def testalterorderwithrespecttoself projectstate self setuptestmodeltestalorwrtto relatedmodeltrue test the state alteration operation migrations alterorderwithrespecttorider pony self assertequal operation describe set orderwithrespectto on rider to pony self assertequal operation migrationnamefragment alterriderorderwithrespectto newstate projectstate clone operation stateforwardstestalorwrtto newstate self assertisnone projectstate modelstestalorwrtto rider options get orderwithrespectto none self assertequal newstate modelstestalorwrtto rider options get orderwithrespectto none pony make sure there s no matching index self assertcolumnnotexiststestalorwrttorider order create some rows before alteration renderedstate projectstate apps pony renderedstate getmodeltestalorwrtto pony objects create weight50 rider1 renderedstate getmodeltestalorwrtto rider objects create ponypony rider1 friend rider1 rider1 save rider2 renderedstate getmodeltestalorwrtto rider objects create ponypony rider2 friend rider2 rider2 save test the database alteration with connection schemaeditor as editor operation databaseforwards testalorwrtto editor projectstate newstate self assertcolumnexiststestalorwrttorider order check for correct value in rows updatedriders newstate apps getmodel testalorwrtto rider objects all self assertequalupdatedriders0 order 0 self assertequalupdatedriders1 order 0 and test reversal with connection schemaeditor as editor operation databasebackwards testalorwrtto editor newstate projectstate self assertcolumnnotexiststestalorwrttorider order and deconstruction definition operation deconstruct self assertequaldefinition0 alterorderwithrespectto self assertequaldefinition1 self assertequal definition2 name rider orderwithrespectto pony def testaltermodelmanagersself projectstate self setuptestmodeltestalmoma test the state alteration operation migrations altermodelmanagers pony managers foodqs foodqueryset asmanager foodmgr foodmanagera b foodmgrkwargs foodmanagerx y 3 4 self assertequaloperation describe change managers on pony self assertequaloperation migrationnamefragment alterponymanagers managers projectstate modelstestalmoma pony managers self assertequalmanagers newstate projectstate clone operation stateforwardstestalmoma newstate self assertintestalmoma pony newstate models managers newstate modelstestalmoma pony managers self assertequalmanagers00 foodqs self assertisinstancemanagers01 models manager self assertequalmanagers10 foodmgr self assertisinstancemanagers11 foodmanager self assertequalmanagers11 args a b 1 2 self assertequalmanagers20 foodmgrkwargs self assertisinstancemanagers21 foodmanager self assertequalmanagers21 args x y 3 4 renderedstate newstate apps model renderedstate getmodeltestalmoma pony self assertisinstancemodel foodqs models manager self assertisinstancemodel foodmgr foodmanager self assertisinstancemodel foodmgrkwargs foodmanager def testaltermodelmanagersemptyingself projectstate self setuptestmodeltestalmomae managermodeltrue test the state alteration operation migrations altermodelmanagersfood managers self assertequaloperation describe change managers on food self assertintestalmomae food projectstate models managers projectstate modelstestalmomae food managers self assertequalmanagers00 foodqs self assertisinstancemanagers01 models manager self assertequalmanagers10 foodmgr self assertisinstancemanagers11 foodmanager self assertequalmanagers11 args a b 1 2 self assertequalmanagers20 foodmgrkwargs self assertisinstancemanagers21 foodmanager self assertequalmanagers21 args x y 3 4 newstate projectstate clone operation stateforwardstestalmomae newstate managers newstate modelstestalmomae food managers self assertequalmanagers def testalterfkself projectstate self setuptestmodeltestalfk test adding and then altering the fk in one go createoperation migrations createmodel namerider fields id models autofieldprimarykeytrue pony models foreignkeypony models cascade createstate projectstate clone createoperation stateforwardstestalfk createstate alteroperation migrations alterfield modelnamerider namepony fieldmodels foreignkeypony models cascade editablefalse alterstate createstate clone alteroperation stateforwardstestalfk alterstate with connection schemaeditor as editor createoperation databaseforwards testalfk editor projectstate createstate alteroperation databaseforwards testalfk editor createstate alterstate def testalterfknonfkself test the state alteration operation migrations alterfield modelnamerider namepony fieldmodels floatfield projectstate newstate self maketeststate testafknfk operation relatedmodeltrue test the database alteration self assertcolumnexiststestafknfkrider ponyid self assertcolumnnotexiststestafknfkrider pony with connection schemaeditor as editor operation databaseforwardstestafknfk editor projectstate newstate self assertcolumnexiststestafknfkrider pony self assertcolumnnotexiststestafknfkrider ponyid and test reversal with connection schemaeditor as editor operation databasebackwards testafknfk editor newstate projectstate self assertcolumnexiststestafknfkrider ponyid self assertcolumnnotexiststestafknfkrider pony def testrunsqlself projectstate self setuptestmodeltestrunsql create the operation operation migrations runsql use a multiline string with a comment to test splitting on sqlite and mysql respectively create table iloveponies id int specialthing varchar15 n insert into iloveponies id specialthing values 1 i love ponies this is magic n insert into iloveponies id specialthing values 2 i love django n update iloveponies set specialthing ponies where specialthing like ponies update iloveponies set specialthing django where specialthing like django run delete queries to test for parameter substitution failure reported in 23426 delete from iloveponies where specialthing like django delete from iloveponies where specialthing like ponies drop table iloveponies stateoperations migrations createmodel somethingelse id models autofieldprimarykeytrue self assertequaloperation describe raw sql operation test the state alteration newstate projectstate clone operation stateforwardstestrunsql newstate self assertequal lennewstate modelstestrunsql somethingelse fields 1 make sure there s no table self asserttablenotexistsiloveponies test sql collection with connection schemaeditorcollectsqltrue as editor operation databaseforwardstestrunsql editor projectstate newstate self assertinlike ponies n joineditor collectedsql operation databasebackwards testrunsql editor projectstate newstate self assertinlike ponies n joineditor collectedsql test the database alteration with connection schemaeditor as editor operation databaseforwardstestrunsql editor projectstate newstate self asserttableexistsiloveponies make sure all the sql was processed with connection cursor as cursor cursor executeselect count from iloveponies self assertequalcursor fetchall00 2 cursor execute select count from iloveponies where specialthing django self assertequalcursor fetchall00 1 cursor execute select count from iloveponies where specialthing ponies self assertequalcursor fetchall00 1 and test reversal self asserttrueoperation reversible with connection schemaeditor as editor operation databasebackwards testrunsql editor newstate projectstate self asserttablenotexistsiloveponies and deconstruction definition operation deconstruct self assertequaldefinition0 runsql self assertequaldefinition1 self assertequal sorteddefinition2 reversesql sql stateoperations and elidable reduction self assertisfalse operation reduceoperation elidableoperation migrations runsqlselect 1 from void elidabletrue self assertequalelidableoperation reduceoperation operation def testrunsqlparamsself 23426 runsql should accept parameters projectstate self setuptestmodeltestrunsql create the operation operation migrations runsql create table iloveponies id int specialthing varchar15 drop table iloveponies paramoperation migrations runsql forwards insert into iloveponies id specialthing values 1 django insert into iloveponies id specialthing values 2 s ponies insert into iloveponies id specialthing values s s 3 python backwards delete from iloveponies where specialthing django delete from iloveponies where specialthing ponies none delete from iloveponies where id s or specialthing s 3 python make sure there s no table self asserttablenotexistsiloveponies newstate projectstate clone test the database alteration with connection schemaeditor as editor operation databaseforwardstestrunsql editor projectstate newstate test parameter passing with connection schemaeditor as editor paramoperation databaseforwards testrunsql editor projectstate newstate make sure all the sql was processed with connection cursor as cursor cursor executeselect count from iloveponies self assertequalcursor fetchall00 3 with connection schemaeditor as editor paramoperation databasebackwards testrunsql editor newstate projectstate with connection cursor as cursor cursor executeselect count from iloveponies self assertequalcursor fetchall00 0 and test reversal with connection schemaeditor as editor operation databasebackwards testrunsql editor newstate projectstate self asserttablenotexistsiloveponies def testrunsqlparamsinvalidself 23426 runsql should fail when a list of statements with an incorrect projectstate self setuptestmodeltestrunsql newstate projectstate clone operation migrations runsql forwards insert into foo bar values buz backwards delete from foo where bar buz invalid parameter count with connection schemaeditor as editor with self assertraisesmessagevalueerror expected a 2tuple but got 1 operation databaseforwards testrunsql editor projectstate newstate with connection schemaeditor as editor with self assertraisesmessagevalueerror expected a 2tuple but got 3 operation databasebackwards testrunsql editor newstate projectstate def testrunsqlnoopself 24098 tests noop runsql operations operation migrations runsqlmigrations runsql noop migrations runsql noop with connection schemaeditor as editor operation databaseforwardstestrunsql editor none none operation databasebackwardstestrunsql editor none none def testrunsqladdmissingsemicolononcollectsqlself projectstate self setuptestmodeltestrunsql newstate projectstate clone tests insert into testrunsqlpony pink weight values 1 1 n insert into testrunsqlpony pink weight values 1 1n for sql in tests with self subtestsqlsql operation migrations runsqlsql migrations runpython noop with connection schemaeditorcollectsqltrue as editor operation databaseforwards testrunsql editor projectstate newstate collectedsql n joineditor collectedsql self assertequalcollectedsql count 1 def testrunpythonself projectstate self setuptestmodeltestrunpython mtimodeltrue create the operation def innermethodmodels schemaeditor pony models getmodeltestrunpython pony pony objects createpink1 weight3 55 pony objects createweight5 def innermethodreversemodels schemaeditor pony models getmodeltestrunpython pony pony objects filterpink1 weight3 55 delete pony objects filterweight5 delete operation migrations runpython innermethod reversecodeinnermethodreverse self assertequaloperation describe raw python operation test the state alteration does nothing newstate projectstate clone operation stateforwardstestrunpython newstate self assertequalnewstate projectstate test the database alteration self assertequal projectstate apps getmodeltestrunpython pony objects count 0 with connection schemaeditor as editor operation databaseforwards testrunpython editor projectstate newstate self assertequal projectstate apps getmodeltestrunpython pony objects count 2 now test reversal self asserttrueoperation reversible with connection schemaeditor as editor operation databasebackwards testrunpython editor projectstate newstate self assertequal projectstate apps getmodeltestrunpython pony objects count 0 now test we can t use a string with self assertraisesmessage valueerror runpython must be supplied with a callable migrations runpythonprint ahahaha and deconstruction definition operation deconstruct self assertequaldefinition0 runpython self assertequaldefinition1 self assertequalsorteddefinition2 code reversecode also test reversal fails with an operation identical to above but without reversecode set noreverseoperation migrations runpythoninnermethod self assertfalsenoreverseoperation reversible with connection schemaeditor as editor noreverseoperation databaseforwards testrunpython editor projectstate newstate with self assertraisesnotimplementederror noreverseoperation databasebackwards testrunpython editor newstate projectstate self assertequal projectstate apps getmodeltestrunpython pony objects count 2 def createponiesmodels schemaeditor pony models getmodeltestrunpython pony pony1 pony objects createpink1 weight3 55 self assertisnotpony1 pk none pony2 pony objects createweight5 self assertisnotpony2 pk none self assertnotequalpony1 pk pony2 pk operation migrations runpythoncreateponies with connection schemaeditor as editor operation databaseforwards testrunpython editor projectstate newstate self assertequal projectstate apps getmodeltestrunpython pony objects count 4 and deconstruction definition operation deconstruct self assertequaldefinition0 runpython self assertequaldefinition1 self assertequalsorteddefinition2 code def createshetlandponiesmodels schemaeditor shetlandpony models getmodeltestrunpython shetlandpony pony1 shetlandpony objects createweight4 0 self assertisnotpony1 pk none pony2 shetlandpony objects createweight5 0 self assertisnotpony2 pk none self assertnotequalpony1 pk pony2 pk operation migrations runpythoncreateshetlandponies with connection schemaeditor as editor operation databaseforwards testrunpython editor projectstate newstate self assertequal projectstate apps getmodeltestrunpython pony objects count 6 self assertequal projectstate apps getmodel testrunpython shetlandpony objects count 2 and elidable reduction self assertisfalse operation reduceoperation elidableoperation migrations runpythoninnermethod elidabletrue self assertequalelidableoperation reduceoperation operation def testrunpythonatomicself projectstate self setuptestmodeltestrunpythonatomic mtimodeltrue def innermethodmodels schemaeditor pony models getmodeltestrunpythonatomic pony pony objects createpink1 weight3 55 raise valueerroradrian hates ponies verify atomicity when applying atomicmigration migrationtest testrunpythonatomic atomicmigration operations migrations runpythoninnermethod reversecodeinnermethod nonatomicmigration migrationtest testrunpythonatomic nonatomicmigration operations migrations runpythoninnermethod reversecodeinnermethod atomicfalse if we re a fullytransactional database both versions should rollback if connection features canrollbackddl self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor atomicmigration applyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor nonatomicmigration applyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 otherwise the nonatomic operation should leave a row there else self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor atomicmigration applyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor nonatomicmigration applyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 1 reset object count to zero and verify atomicity when unapplying projectstate apps getmodel testrunpythonatomic pony objects all delete on a fullytransactional database both versions rollback if connection features canrollbackddl self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor atomicmigration unapplyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor nonatomicmigration unapplyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 otherwise the nonatomic operation leaves a row there else self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor atomicmigration unapplyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 0 with self assertraisesvalueerror with connection schemaeditor as editor nonatomicmigration unapplyprojectstate editor self assertequal projectstate apps getmodel testrunpythonatomic pony objects count 1 verify deconstruction definition nonatomicmigration operations0 deconstruct self assertequaldefinition0 runpython self assertequaldefinition1 self assertequalsorteddefinition2 atomic code reversecode def testrunpythonrelatedassignmentself 24282 model changes to a fk reverse side update the model def innermethodmodels schemaeditor models getmodeltests book models getmodeltestbooks book objects createnamehemingway book objects createtitleold man and the sea create migrations createmodel id models autofieldprimarykeytrue name models charfieldmaxlength100 options createbook migrations createmodel book id models autofieldprimarykeytrue title models charfieldmaxlength100 models foreignkeytests models cascade options addhometown migrations addfield hometown models charfieldmaxlength100 createoldman migrations runpythoninnermethod innermethod projectstate projectstate newstate projectstate clone with connection schemaeditor as editor create stateforwardstests newstate create databaseforwards tests editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor createbook stateforwardstestbooks newstate createbook databaseforwards testbooks editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor addhometown stateforwardstests newstate addhometown databaseforwards tests editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor createoldman stateforwardstestbooks newstate createoldman databaseforwards testbooks editor projectstate newstate def testmodelwithbigautofieldself def createdatamodels schemaeditor models getmodeltest book models getmodeltestbook book 1 objects createnamehemingway book objects createtitleold man and the sea 1 book objects createid233 titlea farewell to arms 1 2 objects createid233 nameremarque book objects createtitleall quiet on the western front 2 book objects createtitlearc de triomphe 2 create migrations createmodel id models bigautofieldprimarykeytrue name models charfieldmaxlength100 options createbook migrations createmodel book id models bigautofieldprimarykeytrue title models charfieldmaxlength100 models foreignkey totest ondeletemodels cascade options filldata migrations runpythoncreatedata projectstate projectstate newstate projectstate clone with connection schemaeditor as editor create stateforwardstest newstate create databaseforwards test editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor createbook stateforwardstestbook newstate createbook databaseforwardstestbook editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor filldata stateforwardsfilldata newstate filldata databaseforwardsfilldata editor projectstate newstate def testautofieldforeignfieldgrowth self sourcefield targetfield targetvalue def createinitialdatamodels schemaeditor article models getmodeltestarticle article blog models getmodeltestblog blog blog blog objects createnameweb development done right article objects createnameframeworks blogblog article objects createnameprogramming languages blogblog def createbigdatamodels schemaeditor article models getmodeltestarticle article blog models getmodeltestblog blog blog2 blog objects createnameframeworks idtargetvalue article objects createnamedjango blogblog2 article objects createidtargetvalue namedjango2 blogblog2 createblog migrations createmodel blog id sourcefieldprimarykeytrue name models charfieldmaxlength100 options createarticle migrations createmodel article id sourcefieldprimarykeytrue blog models foreignkeytotestblog blog ondeletemodels cascade name models charfieldmaxlength100 data models textfielddefault options fillinitialdata migrations runpython createinitialdata createinitialdata fillbigdata migrations runpythoncreatebigdata createbigdata growarticleid migrations alterfield article id targetfieldprimarykeytrue growblogid migrations alterfield blog id targetfieldprimarykeytrue projectstate projectstate newstate projectstate clone with connection schemaeditor as editor createblog stateforwardstestblog newstate createblog databaseforwardstestblog editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor createarticle stateforwardstestarticle newstate createarticle databaseforwards testarticle editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor fillinitialdata stateforwardsfillinitialdata newstate fillinitialdata databaseforwards fillinitialdata editor projectstate newstate projectstate newstate newstate newstate clone with connection schemaeditor as editor growarticleid stateforwardstestarticle newstate growarticleid databaseforwards testarticle editor projectstate newstate state newstate clone article state apps getmodeltestarticle article self assertisinstancearticle meta pk targetfield projectstate newstate newstate newstate clone with connection schemaeditor as editor growblogid stateforwardstestblog newstate growblogid databaseforwards testblog editor projectstate newstate state newstate clone blog state apps getmodeltestblog blog self assertisinstanceblog meta pk targetfield projectstate newstate newstate newstate clone with connection schemaeditor as editor fillbigdata stateforwardsfillbigdata newstate fillbigdata databaseforwards fillbigdata editor projectstate newstate def testautofieldbigautofieldforeignfieldgrowthself a field may be migrated from smallautofield to autofield self testautofieldforeignfieldgrowth models smallautofield models autofield 222 def testsmallfieldbigautofieldforeignfieldgrowthself 24098 tests noop runpython operations tests the separatedatabaseandstate operation create the operation test the state alteration make sure there s no table test the database alteration and test reversal and deconstruction a complex separatedatabaseandstate operation multiple operations both for state and database verify the state dependencies within each list and that state ops don t affect the database create the operation we use integerfield and not autofield because the model is going to be deleted immediately and with an autofield this fails on oracle test the state alteration tables and models exist or don t as they should test the database alteration and test reversal add generated column reversal add generated column remove generated column key operations ignore swappable models we don t want to replicate all of them here as the functionality is in a common base class anyway the createtable operation ignores swapped models test the state alteration it should still be there test the database alteration and test reversal tests the deletemodel operation ignores swapped models test the database alteration and test reversal tests the addfield operation test the state alteration test the database alteration and test reversal addremoveindex operations ignore swapped models no database queries should be run for swapped models model name match referenced field doesn t reference tests running the operations and making sure they do what they say they do each test looks at their state changing and then their database operation both forwards and backwards tests the createmodel operation most other tests use this operation as part of setup so check failures here first test the state alteration test the database alteration and test reversal and deconstruction and default manager not in set tests the createmodel operation directly followed by an alteruniquetogether bug 22844 sqlite remake issues test the database alteration test the creation of a model with a manytomany field and the auto created through model test the state alteration test the database alteration make sure the m2m field actually works and test reversal creation of models with a fk to a pk with db_collation foreignkey reversal onetoonefield reversal tests the createmodel operation on a multi table inheritance setup test the state alteration test the database alteration and test reversal createmodel ignores proxy models test the state alteration test the database alteration and test reversal and deconstruction createmodel ignores unmanaged models test the state alteration test the database alteration and test reversal test the state alteration test database alteration test reversal test deconstruction add table test the state alteration test database alteration test constraint works test reversal test deconstruction create table unique constraint is deferred constraint behavior can be changed with set constraints reversal deconstruction create table reversal deconstruction the managers on a model are set test the state alteration tests the deletemodel operation test the state alteration test the database alteration and test reversal and deconstruction tests the deletemodel operation ignores proxy models test the state alteration test the database alteration and test reversal test the state alteration test the database alteration and test reversal tests the renamemodel operation test the state alteration test initial state and database migrate forwards test new state and database renamemodel also repoints all incoming fks and m2ms migrate backwards test original state and database and deconstruction renamemodel operations shouldn t trigger the caching of rendered apps on state without prior apps now with apps cached tests the renamemodel operation on model with self referential fk test the state alteration remember renamemodel also repoints all incoming fks and m2ms test the database alteration and test reversal tests the renamemodel operation on a model which has a superclass that has a foreign key test the state alteration renamemodel shouldn t repoint the superclass s relations only local ones before running the migration we have a table for shetland pony not little horse and the foreign key on rider points to pony not shetland pony now we have a little horse table not shetland pony but the foreign keys still point at pony not little horse rename model reversal renamemodel renames a many to many column after a renamefield no no such column error means the column was renamed correctly tests the addfield operation test the state alteration test the database alteration and test reversal and deconstruction tests the addfield operation on textfield if not properly quoted digits would be interpreted as an int manual quoting is fragile and could trip on quotes refs xyz tests the addfield operation on textfield if not properly quoted digits would be interpreted as an int manual quoting is fragile and could trip on quotes refs xyz tests the addfield operation on textfield binaryfield if not properly quoted digits would be interpreted as an int manual quoting is fragile and could trip on quotes refs xyz sqlite returns buffer memoryview cast to bytes for checking column names that are sql keywords shouldn t cause problems when used in migrations 22168 tests the addfield operation s state alteration when preserve_default false test the state alteration test the database alteration and deconstruction the addfield operation can set and unset a database default add field reversal deconstruction the single quotation mark is properly quoted and is set for new rows on oracle however it is not set on existing rows skip the assertion as it s probably a bug in oracle add field the addfield operation with both default and db_default add field reversal deconstruction tests the addfield operation with a manytomanyfield test the state alteration test the database alteration make sure the m2m field actually works and test reversal ensure the new field actually works and test reversal tests the removefield operation test the state alteration test the database alteration and test reversal and deconstruction tests the removefield operation on a foreign key tests the altermodeltable operation test the state alteration test the database alteration and test reversal and deconstruction tests the altermodeltable operation if the table name is set to none tests the altermodeltable operation if the table name is not changed test the state alteration test the database alteration and test reversal altermodeltable should rename auto generated m2m tables add the m2m field rename the pony db_table which should also rename the m2m table and test reversal add the m2m field point the m2m field to self reversal tests the alterfield operation test the state alteration test the database alteration and test reversal and deconstruction alter field reversal deconstruction the alterfield operation changing default to db_default alter field reversal the alterfield operation changing a null field to db_default alter field reversal add field alter field alter field reversal alterfield operation is a noop when adding only a db_column and the column name is not changed add table comment reversal deconstruction the alterfield operation on primary keys things like postgresql s serial weirdness test the state alteration test the database alteration and test reversal tests the alterfield operation on primary keys changes any fks pointing to it test the state alteration test the database alteration and test reversal alterfield operation of db_collation on primary keys changes any fks pointing to it state alteration database alteration reversal alter primary key reversal alter primary key reversal if alterfield doesn t reload state appropriately the second alterfield crashes on mysql due to not dropping the ponyrider pony foreign key constraint before modifying the column if alterfield doesn t reload state appropriately the second alterfield crashes on mysql due to not dropping the ponyrider pony foreign key constraint before modifying the column if renamefield doesn t reload state appropriately the alterfield crashes on mysql due to not dropping the ponyrider pony foreign key constraint before modifying the column tests the renamefield operation rename field reversal deconstruction unique_together has the renamed column rename field the unique constraint has been ported over reversal tests the alteruniquetogether operation test the state alteration make sure we can insert duplicate rows test the database alteration and test reversal test flat unique_together and deconstruction test the addindex operation test the database alteration and test reversal and deconstruction test the removeindex operation test the state alteration test the database alteration and test reversal and deconstruction also test a field dropped with index sqlite remake issue test database alteration and test reversal rename index reversal deconstruction add index reversal deconstruction remove index reversal deconstruction test alterfield operation with an index to ensure indexes created via meta indexes don t get dropped with sqlite3 remake test the database alteration index hasn t been dropped and test reversal ensure the index is still there test the state alteration test the database alteration add another one test reversal test deconstruction generated in startswith lookup should be escaped in a way that is considered a leading wildcard literal should be escaped in a way that is not a considered a wildcard right hand side baked literals should not be used for parameters interpolation exact matches against literals should also be supported test state alteration test database alteration remove the other one test reversal test deconstruction test the state alteration test the database alteration test constraint works test reversal test constraint doesn t work test deconstruction test state alteration test database alteration test constraint doesn t work test reversal test constraint works test deconstruction add constraint unique constraint is deferred constraint behavior can be changed with set constraints reversal constraint doesn t work deconstruction remove constraint constraint doesn t work reversal unique constraint is deferred constraint behavior can be changed with set constraints deconstruction add constraint reversal constraint doesn t work deconstruction remove constraint constraint doesn t work reversal deconstruction add constraint reversal constraint doesn t work deconstruction remove constraint constraint doesn t work reversal deconstruction tests the altermodeloptions operation test the state alteration no db alteration to test and deconstruction the altermodeloptions operation removes keys from the dict 23121 test the state alteration no db alteration to test and deconstruction tests the alterorderwithrespectto operation test the state alteration make sure there s no matching index create some rows before alteration test the database alteration check for correct value in rows and test reversal and deconstruction the managers on a model are set test the state alteration the managers on a model are set test the state alteration creating and then altering an fk works correctly and deals with the pending sql 23091 test adding and then altering the fk in one go altering an fk to a non fk works 23244 test the state alteration test the database alteration and test reversal tests the runsql operation create the operation use a multi line string with a comment to test splitting on sqlite and mysql respectively run delete queries to test for parameter substitution failure reported in 23426 test the state alteration make sure there s no table test sql collection test the database alteration make sure all the sql was processed and test reversal and deconstruction and elidable reduction 23426 runsql should accept parameters create the operation forwards backwards make sure there s no table test the database alteration test parameter passing make sure all the sql was processed and test reversal 23426 runsql should fail when a list of statements with an incorrect number of tuples is given forwards backwards 24098 tests no op runsql operations tests the runpython operation create the operation test the state alteration does nothing test the database alteration now test reversal now test we can t use a string and deconstruction also test reversal fails with an operation identical to above but without reverse_code set and deconstruction and elidable reduction tests the runpython operation correctly handles the atomic keyword verify atomicity when applying if we re a fully transactional database both versions should rollback otherwise the non atomic operation should leave a row there reset object count to zero and verify atomicity when unapplying on a fully transactional database both versions rollback otherwise the non atomic operation leaves a row there verify deconstruction 24282 model changes to a fk reverse side update the model on the fk side as well a model with bigautofield can be created a field may be migrated in the following ways autofield to bigautofield smallautofield to autofield smallautofield to bigautofield a field may be migrated from autofield to bigautofield a field may be migrated from smallautofield to autofield a field may be migrated from smallautofield to bigautofield 24098 tests no op runpython operations tests the separatedatabaseandstate operation create the operation test the state alteration make sure there s no table test the database alteration and test reversal and deconstruction a complex separatedatabaseandstate operation multiple operations both for state and database verify the state dependencies within each list and that state ops don t affect the database create the operation we use integerfield and not autofield because the model is going to be deleted immediately and with an autofield this fails on oracle test the state alteration tables and models exist or don t as they should test the database alteration and test reversal add generated column reversal add generated column remove generated column key operations ignore swappable models we don t want to replicate all of them here as the functionality is in a common base class anyway the createtable operation ignores swapped models test the state alteration it should still be there test the database alteration and test reversal tests the deletemodel operation ignores swapped models test the database alteration and test reversal tests the addfield operation test the state alteration test the database alteration and test reversal add removeindex operations ignore swapped models no database queries should be run for swapped models model name match referenced field doesn t reference
import math
from decimal import Decimal

from django.core.exceptions import FieldDoesNotExist
from django.db import IntegrityError, connection, migrations, models, transaction
from django.db.migrations.migration import Migration
from django.db.migrations.operations.fields import FieldOperation
from django.db.migrations.state import ModelState, ProjectState
from django.db.models import F
from django.db.models.expressions import Value
from django.db.models.functions import Abs, Pi
from django.db.transaction import atomic
from django.test import (
    SimpleTestCase,
    override_settings,
    skipIfDBFeature,
    skipUnlessDBFeature,
)
from django.test.utils import CaptureQueriesContext

from .models import FoodManager, FoodQuerySet, UnicodeModel
from .test_base import OperationTestBase


class Mixin:
    pass


class OperationTests(OperationTestBase):
    

    def test_create_model(self):
        
        operation = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=1)),
            ],
        )
        self.assertEqual(operation.describe(), "Create model Pony")
        self.assertEqual(operation.migration_name_fragment, "pony")
        
        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards("test_crmo", new_state)
        self.assertEqual(new_state.models["test_crmo", "pony"].name, "Pony")
        self.assertEqual(len(new_state.models["test_crmo", "pony"].fields), 2)
        
        self.assertTableNotExists("test_crmo_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmo", editor, project_state, new_state)
        self.assertTableExists("test_crmo_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_crmo", editor, new_state, project_state)
        self.assertTableNotExists("test_crmo_pony")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "CreateModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["fields", "name"])
        
        operation = migrations.CreateModel(
            "Foo", fields=[], managers=[("objects", models.Manager())]
        )
        definition = operation.deconstruct()
        self.assertNotIn("managers", definition[2])

    def test_create_model_with_duplicate_field_name(self):
        with self.assertRaisesMessage(
            ValueError, "Found duplicate value pink in CreateModel fields argument."
        ):
            migrations.CreateModel(
                "Pony",
                [
                    ("id", models.AutoField(primary_key=True)),
                    ("pink", models.TextField()),
                    ("pink", models.IntegerField(default=1)),
                ],
            )

    def test_create_model_with_duplicate_base(self):
        message = "Found duplicate value test_crmo.pony in CreateModel bases argument."
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    "test_crmo.Pony",
                    "test_crmo.Pony",
                ),
            )
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    "test_crmo.Pony",
                    "test_crmo.pony",
                ),
            )
        message = (
            "Found duplicate value migrations.unicodemodel in CreateModel bases "
            "argument."
        )
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    UnicodeModel,
                    UnicodeModel,
                ),
            )
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    UnicodeModel,
                    "migrations.unicodemodel",
                ),
            )
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    UnicodeModel,
                    "migrations.UnicodeModel",
                ),
            )
        message = (
            "Found duplicate value <class 'django.db.models.base.Model'> in "
            "CreateModel bases argument."
        )
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    models.Model,
                    models.Model,
                ),
            )
        message = (
            "Found duplicate value <class 'migrations.test_operations.Mixin'> in "
            "CreateModel bases argument."
        )
        with self.assertRaisesMessage(ValueError, message):
            migrations.CreateModel(
                "Pony",
                fields=[],
                bases=(
                    Mixin,
                    Mixin,
                ),
            )

    def test_create_model_with_duplicate_manager_name(self):
        with self.assertRaisesMessage(
            ValueError,
            "Found duplicate value objects in CreateModel managers argument.",
        ):
            migrations.CreateModel(
                "Pony",
                fields=[],
                managers=[
                    ("objects", models.Manager()),
                    ("objects", models.Manager()),
                ],
            )

    def test_create_model_with_unique_after(self):
        
        operation1 = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=1)),
            ],
        )
        operation2 = migrations.CreateModel(
            "Rider",
            [
                ("id", models.AutoField(primary_key=True)),
                ("number", models.IntegerField(default=1)),
                ("pony", models.ForeignKey("test_crmoua.Pony", models.CASCADE)),
            ],
        )
        operation3 = migrations.AlterUniqueTogether(
            "Rider",
            [
                ("number", "pony"),
            ],
        )
        
        project_state = ProjectState()
        self.assertTableNotExists("test_crmoua_pony")
        self.assertTableNotExists("test_crmoua_rider")
        with connection.schema_editor() as editor:
            new_state = project_state.clone()
            operation1.state_forwards("test_crmoua", new_state)
            operation1.database_forwards(
                "test_crmoua", editor, project_state, new_state
            )
            project_state, new_state = new_state, new_state.clone()
            operation2.state_forwards("test_crmoua", new_state)
            operation2.database_forwards(
                "test_crmoua", editor, project_state, new_state
            )
            project_state, new_state = new_state, new_state.clone()
            operation3.state_forwards("test_crmoua", new_state)
            operation3.database_forwards(
                "test_crmoua", editor, project_state, new_state
            )
        self.assertTableExists("test_crmoua_pony")
        self.assertTableExists("test_crmoua_rider")

    def test_create_model_m2m(self):
        
        project_state = self.set_up_test_model("test_crmomm")
        operation = migrations.CreateModel(
            "Stable",
            [
                ("id", models.AutoField(primary_key=True)),
                ("ponies", models.ManyToManyField("Pony", related_name="stables")),
            ],
        )
        
        new_state = project_state.clone()
        operation.state_forwards("test_crmomm", new_state)
        
        self.assertTableNotExists("test_crmomm_stable_ponies")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmomm", editor, project_state, new_state)
        self.assertTableExists("test_crmomm_stable")
        self.assertTableExists("test_crmomm_stable_ponies")
        self.assertColumnNotExists("test_crmomm_stable", "ponies")
        
        with atomic():
            Pony = new_state.apps.get_model("test_crmomm", "Pony")
            Stable = new_state.apps.get_model("test_crmomm", "Stable")
            stable = Stable.objects.create()
            p1 = Pony.objects.create(pink=False, weight=4.55)
            p2 = Pony.objects.create(pink=True, weight=5.43)
            stable.ponies.add(p1, p2)
            self.assertEqual(stable.ponies.count(), 2)
            stable.ponies.all().delete()
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_crmomm", editor, new_state, project_state
            )
        self.assertTableNotExists("test_crmomm_stable")
        self.assertTableNotExists("test_crmomm_stable_ponies")

    @skipUnlessDBFeature("supports_collation_on_charfield", "supports_foreign_keys")
    def test_create_fk_models_to_pk_field_db_collation(self):
        
        collation = connection.features.test_collations.get("non_default")
        if not collation:
            self.skipTest("Language collations are not supported.")

        app_label = "test_cfkmtopkfdbc"
        operations = [
            migrations.CreateModel(
                "Pony",
                [
                    (
                        "id",
                        models.CharField(
                            primary_key=True,
                            max_length=10,
                            db_collation=collation,
                        ),
                    ),
                ],
            )
        ]
        project_state = self.apply_operations(app_label, ProjectState(), operations)
        
        new_state = project_state.clone()
        operation = migrations.CreateModel(
            "Rider",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pony", models.ForeignKey("Pony", models.CASCADE)),
            ],
        )
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnCollation(f"{app_label}_rider", "pony_id", collation)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        
        new_state = project_state.clone()
        operation = migrations.CreateModel(
            "ShetlandPony",
            [
                (
                    "pony",
                    models.OneToOneField("Pony", models.CASCADE, primary_key=True),
                ),
                ("cuteness", models.IntegerField(default=1)),
            ],
        )
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnCollation(f"{app_label}_shetlandpony", "pony_id", collation)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)

    def test_create_model_inheritance(self):
        
        project_state = self.set_up_test_model("test_crmoih")
        
        operation = migrations.CreateModel(
            "ShetlandPony",
            [
                (
                    "pony_ptr",
                    models.OneToOneField(
                        "test_crmoih.Pony",
                        models.CASCADE,
                        auto_created=True,
                        primary_key=True,
                        to_field="id",
                        serialize=False,
                    ),
                ),
                ("cuteness", models.IntegerField(default=1)),
            ],
        )
        new_state = project_state.clone()
        operation.state_forwards("test_crmoih", new_state)
        self.assertIn(("test_crmoih", "shetlandpony"), new_state.models)
        
        self.assertTableNotExists("test_crmoih_shetlandpony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmoih", editor, project_state, new_state)
        self.assertTableExists("test_crmoih_shetlandpony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_crmoih", editor, new_state, project_state
            )
        self.assertTableNotExists("test_crmoih_shetlandpony")

    def test_create_proxy_model(self):
        
        project_state = self.set_up_test_model("test_crprmo")
        
        operation = migrations.CreateModel(
            "ProxyPony",
            [],
            options={"proxy": True},
            bases=("test_crprmo.Pony",),
        )
        self.assertEqual(operation.describe(), "Create proxy model ProxyPony")
        new_state = project_state.clone()
        operation.state_forwards("test_crprmo", new_state)
        self.assertIn(("test_crprmo", "proxypony"), new_state.models)
        
        self.assertTableNotExists("test_crprmo_proxypony")
        self.assertTableExists("test_crprmo_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crprmo", editor, project_state, new_state)
        self.assertTableNotExists("test_crprmo_proxypony")
        self.assertTableExists("test_crprmo_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_crprmo", editor, new_state, project_state
            )
        self.assertTableNotExists("test_crprmo_proxypony")
        self.assertTableExists("test_crprmo_pony")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "CreateModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["bases", "fields", "name", "options"])

    def test_create_unmanaged_model(self):
        
        project_state = self.set_up_test_model("test_crummo")
        
        operation = migrations.CreateModel(
            "UnmanagedPony",
            [],
            options={"proxy": True},
            bases=("test_crummo.Pony",),
        )
        self.assertEqual(operation.describe(), "Create proxy model UnmanagedPony")
        new_state = project_state.clone()
        operation.state_forwards("test_crummo", new_state)
        self.assertIn(("test_crummo", "unmanagedpony"), new_state.models)
        
        self.assertTableNotExists("test_crummo_unmanagedpony")
        self.assertTableExists("test_crummo_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crummo", editor, project_state, new_state)
        self.assertTableNotExists("test_crummo_unmanagedpony")
        self.assertTableExists("test_crummo_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_crummo", editor, new_state, project_state
            )
        self.assertTableNotExists("test_crummo_unmanagedpony")
        self.assertTableExists("test_crummo_pony")

    @skipUnlessDBFeature("supports_table_check_constraints")
    def test_create_model_with_constraint(self):
        where = models.Q(pink__gt=2)
        check_constraint = models.CheckConstraint(
            check=where, name="test_constraint_pony_pink_gt_2"
        )
        operation = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=3)),
            ],
            options={"constraints": [check_constraint]},
        )

        
        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards("test_crmo", new_state)
        self.assertEqual(
            len(new_state.models["test_crmo", "pony"].options["constraints"]), 1
        )

        
        self.assertTableNotExists("test_crmo_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmo", editor, project_state, new_state)
        self.assertTableExists("test_crmo_pony")
        with connection.cursor() as cursor:
            with self.assertRaises(IntegrityError):
                cursor.execute("INSERT INTO test_crmo_pony (id, pink) VALUES (1, 1)")

        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_crmo", editor, new_state, project_state)
        self.assertTableNotExists("test_crmo_pony")

        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "CreateModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2]["options"]["constraints"], [check_constraint])

    @skipUnlessDBFeature("supports_table_check_constraints")
    def test_create_model_with_boolean_expression_in_check_constraint(self):
        app_label = "test_crmobechc"
        rawsql_constraint = models.CheckConstraint(
            check=models.expressions.RawSQL(
                "price < %s", (1000,), output_field=models.BooleanField()
            ),
            name=f"{app_label}_price_lt_1000_raw",
        )
        wrapper_constraint = models.CheckConstraint(
            check=models.expressions.ExpressionWrapper(
                models.Q(price__gt=500) | models.Q(price__lt=500),
                output_field=models.BooleanField(),
            ),
            name=f"{app_label}_price_neq_500_wrap",
        )
        operation = migrations.CreateModel(
            "Product",
            [
                ("id", models.AutoField(primary_key=True)),
                ("price", models.IntegerField(null=True)),
            ],
            options={"constraints": [rawsql_constraint, wrapper_constraint]},
        )

        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        
        self.assertTableNotExists(app_label)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertTableExists(f"{app_label}_product")
        insert_sql = f"INSERT INTO {app_label}_product (id, price) VALUES (%d, %d)"
        with connection.cursor() as cursor:
            with self.assertRaises(IntegrityError):
                cursor.execute(insert_sql % (1, 1000))
            cursor.execute(insert_sql % (1, 999))
            with self.assertRaises(IntegrityError):
                cursor.execute(insert_sql % (2, 500))
            cursor.execute(insert_sql % (2, 499))

    def test_create_model_with_partial_unique_constraint(self):
        partial_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            condition=models.Q(weight__gt=5),
            name="test_constraint_pony_pink_for_weight_gt_5_uniq",
        )
        operation = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=3)),
                ("weight", models.FloatField()),
            ],
            options={"constraints": [partial_unique_constraint]},
        )
        
        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards("test_crmo", new_state)
        self.assertEqual(
            len(new_state.models["test_crmo", "pony"].options["constraints"]), 1
        )
        
        self.assertTableNotExists("test_crmo_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmo", editor, project_state, new_state)
        self.assertTableExists("test_crmo_pony")
        
        Pony = new_state.apps.get_model("test_crmo", "Pony")
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=6.0)
        if connection.features.supports_partial_indexes:
            with self.assertRaises(IntegrityError):
                Pony.objects.create(pink=1, weight=7.0)
        else:
            Pony.objects.create(pink=1, weight=7.0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_crmo", editor, new_state, project_state)
        self.assertTableNotExists("test_crmo_pony")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "CreateModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2]["options"]["constraints"], [partial_unique_constraint]
        )

    def test_create_model_with_deferred_unique_constraint(self):
        deferred_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            name="deferrable_pink_constraint",
            deferrable=models.Deferrable.DEFERRED,
        )
        operation = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=3)),
            ],
            options={"constraints": [deferred_unique_constraint]},
        )
        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards("test_crmo", new_state)
        self.assertEqual(
            len(new_state.models["test_crmo", "pony"].options["constraints"]), 1
        )
        self.assertTableNotExists("test_crmo_pony")
        
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmo", editor, project_state, new_state)
        self.assertTableExists("test_crmo_pony")
        Pony = new_state.apps.get_model("test_crmo", "Pony")
        Pony.objects.create(pink=1)
        if connection.features.supports_deferrable_unique_constraints:
            
            with transaction.atomic():
                obj = Pony.objects.create(pink=1)
                obj.pink = 2
                obj.save()
            
            with self.assertRaises(IntegrityError):
                with transaction.atomic(), connection.cursor() as cursor:
                    quoted_name = connection.ops.quote_name(
                        deferred_unique_constraint.name
                    )
                    cursor.execute("SET CONSTRAINTS %s IMMEDIATE" % quoted_name)
                    obj = Pony.objects.create(pink=1)
                    obj.pink = 3
                    obj.save()
        else:
            Pony.objects.create(pink=1)
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_crmo", editor, new_state, project_state)
        self.assertTableNotExists("test_crmo_pony")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "CreateModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2]["options"]["constraints"],
            [deferred_unique_constraint],
        )

    @skipUnlessDBFeature("supports_covering_indexes")
    def test_create_model_with_covering_unique_constraint(self):
        covering_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            include=["weight"],
            name="test_constraint_pony_pink_covering_weight",
        )
        operation = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=3)),
                ("weight", models.FloatField()),
            ],
            options={"constraints": [covering_unique_constraint]},
        )
        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards("test_crmo", new_state)
        self.assertEqual(
            len(new_state.models["test_crmo", "pony"].options["constraints"]), 1
        )
        self.assertTableNotExists("test_crmo_pony")
        
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crmo", editor, project_state, new_state)
        self.assertTableExists("test_crmo_pony")
        Pony = new_state.apps.get_model("test_crmo", "Pony")
        Pony.objects.create(pink=1, weight=4.0)
        with self.assertRaises(IntegrityError):
            Pony.objects.create(pink=1, weight=7.0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_crmo", editor, new_state, project_state)
        self.assertTableNotExists("test_crmo_pony")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "CreateModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2]["options"]["constraints"],
            [covering_unique_constraint],
        )

    def test_create_model_managers(self):
        
        project_state = self.set_up_test_model("test_cmoma")
        
        operation = migrations.CreateModel(
            "Food",
            fields=[
                ("id", models.AutoField(primary_key=True)),
            ],
            managers=[
                ("food_qs", FoodQuerySet.as_manager()),
                ("food_mgr", FoodManager("a", "b")),
                ("food_mgr_kwargs", FoodManager("x", "y", 3, 4)),
            ],
        )
        self.assertEqual(operation.describe(), "Create model Food")
        new_state = project_state.clone()
        operation.state_forwards("test_cmoma", new_state)
        self.assertIn(("test_cmoma", "food"), new_state.models)
        managers = new_state.models["test_cmoma", "food"].managers
        self.assertEqual(managers[0][0], "food_qs")
        self.assertIsInstance(managers[0][1], models.Manager)
        self.assertEqual(managers[1][0], "food_mgr")
        self.assertIsInstance(managers[1][1], FoodManager)
        self.assertEqual(managers[1][1].args, ("a", "b", 1, 2))
        self.assertEqual(managers[2][0], "food_mgr_kwargs")
        self.assertIsInstance(managers[2][1], FoodManager)
        self.assertEqual(managers[2][1].args, ("x", "y", 3, 4))

    def test_delete_model(self):
        
        project_state = self.set_up_test_model("test_dlmo")
        
        operation = migrations.DeleteModel("Pony")
        self.assertEqual(operation.describe(), "Delete model Pony")
        self.assertEqual(operation.migration_name_fragment, "delete_pony")
        new_state = project_state.clone()
        operation.state_forwards("test_dlmo", new_state)
        self.assertNotIn(("test_dlmo", "pony"), new_state.models)
        
        self.assertTableExists("test_dlmo_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_dlmo", editor, project_state, new_state)
        self.assertTableNotExists("test_dlmo_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_dlmo", editor, new_state, project_state)
        self.assertTableExists("test_dlmo_pony")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "DeleteModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(list(definition[2]), ["name"])

    def test_delete_proxy_model(self):
        
        project_state = self.set_up_test_model("test_dlprmo", proxy_model=True)
        
        operation = migrations.DeleteModel("ProxyPony")
        new_state = project_state.clone()
        operation.state_forwards("test_dlprmo", new_state)
        self.assertIn(("test_dlprmo", "proxypony"), project_state.models)
        self.assertNotIn(("test_dlprmo", "proxypony"), new_state.models)
        
        self.assertTableExists("test_dlprmo_pony")
        self.assertTableNotExists("test_dlprmo_proxypony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_dlprmo", editor, project_state, new_state)
        self.assertTableExists("test_dlprmo_pony")
        self.assertTableNotExists("test_dlprmo_proxypony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_dlprmo", editor, new_state, project_state
            )
        self.assertTableExists("test_dlprmo_pony")
        self.assertTableNotExists("test_dlprmo_proxypony")

    def test_delete_mti_model(self):
        project_state = self.set_up_test_model("test_dlmtimo", mti_model=True)
        
        operation = migrations.DeleteModel("ShetlandPony")
        new_state = project_state.clone()
        operation.state_forwards("test_dlmtimo", new_state)
        self.assertIn(("test_dlmtimo", "shetlandpony"), project_state.models)
        self.assertNotIn(("test_dlmtimo", "shetlandpony"), new_state.models)
        
        self.assertTableExists("test_dlmtimo_pony")
        self.assertTableExists("test_dlmtimo_shetlandpony")
        self.assertColumnExists("test_dlmtimo_shetlandpony", "pony_ptr_id")
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_dlmtimo", editor, project_state, new_state
            )
        self.assertTableExists("test_dlmtimo_pony")
        self.assertTableNotExists("test_dlmtimo_shetlandpony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_dlmtimo", editor, new_state, project_state
            )
        self.assertTableExists("test_dlmtimo_pony")
        self.assertTableExists("test_dlmtimo_shetlandpony")
        self.assertColumnExists("test_dlmtimo_shetlandpony", "pony_ptr_id")

    def test_rename_model(self):
        
        project_state = self.set_up_test_model("test_rnmo", related_model=True)
        
        operation = migrations.RenameModel("Pony", "Horse")
        self.assertEqual(operation.describe(), "Rename model Pony to Horse")
        self.assertEqual(operation.migration_name_fragment, "rename_pony_horse")
        
        self.assertIn(("test_rnmo", "pony"), project_state.models)
        self.assertNotIn(("test_rnmo", "horse"), project_state.models)
        self.assertTableExists("test_rnmo_pony")
        self.assertTableNotExists("test_rnmo_horse")
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                "test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id")
            )
            self.assertFKNotExists(
                "test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id")
            )
        
        new_state = project_state.clone()
        new_state = self.apply_operations("test_rnmo", new_state, [operation])
        
        self.assertNotIn(("test_rnmo", "pony"), new_state.models)
        self.assertIn(("test_rnmo", "horse"), new_state.models)
        
        self.assertEqual(
            new_state.models["test_rnmo", "rider"].fields["pony"].remote_field.model,
            "test_rnmo.Horse",
        )
        self.assertTableNotExists("test_rnmo_pony")
        self.assertTableExists("test_rnmo_horse")
        if connection.features.supports_foreign_keys:
            self.assertFKNotExists(
                "test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id")
            )
            self.assertFKExists(
                "test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id")
            )
        
        original_state = self.unapply_operations(
            "test_rnmo", project_state, [operation]
        )
        
        self.assertIn(("test_rnmo", "pony"), original_state.models)
        self.assertNotIn(("test_rnmo", "horse"), original_state.models)
        self.assertEqual(
            original_state.models["test_rnmo", "rider"]
            .fields["pony"]
            .remote_field.model,
            "Pony",
        )
        self.assertTableExists("test_rnmo_pony")
        self.assertTableNotExists("test_rnmo_horse")
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                "test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id")
            )
            self.assertFKNotExists(
                "test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id")
            )
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RenameModel")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"old_name": "Pony", "new_name": "Horse"})

    def test_rename_model_state_forwards(self):
        
        state = ProjectState()
        state.add_model(ModelState("migrations", "Foo", []))
        operation = migrations.RenameModel("Foo", "Bar")
        operation.state_forwards("migrations", state)
        self.assertNotIn("apps", state.__dict__)
        self.assertNotIn(("migrations", "foo"), state.models)
        self.assertIn(("migrations", "bar"), state.models)
        
        apps = state.apps
        operation = migrations.RenameModel("Bar", "Foo")
        operation.state_forwards("migrations", state)
        self.assertIs(state.apps, apps)
        self.assertNotIn(("migrations", "bar"), state.models)
        self.assertIn(("migrations", "foo"), state.models)

    def test_rename_model_with_self_referential_fk(self):
        
        project_state = self.set_up_test_model("test_rmwsrf", related_model=True)
        
        operation = migrations.RenameModel("Rider", "HorseRider")
        self.assertEqual(operation.describe(), "Rename model Rider to HorseRider")
        new_state = project_state.clone()
        operation.state_forwards("test_rmwsrf", new_state)
        self.assertNotIn(("test_rmwsrf", "rider"), new_state.models)
        self.assertIn(("test_rmwsrf", "horserider"), new_state.models)
        
        self.assertEqual(
            "self",
            new_state.models["test_rmwsrf", "horserider"]
            .fields["friend"]
            .remote_field.model,
        )
        HorseRider = new_state.apps.get_model("test_rmwsrf", "horserider")
        self.assertIs(
            HorseRider._meta.get_field("horserider").remote_field.model, HorseRider
        )
        
        self.assertTableExists("test_rmwsrf_rider")
        self.assertTableNotExists("test_rmwsrf_horserider")
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                "test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_rider", "id")
            )
            self.assertFKNotExists(
                "test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_horserider", "id")
            )
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rmwsrf", editor, project_state, new_state)
        self.assertTableNotExists("test_rmwsrf_rider")
        self.assertTableExists("test_rmwsrf_horserider")
        if connection.features.supports_foreign_keys:
            self.assertFKNotExists(
                "test_rmwsrf_horserider", ["friend_id"], ("test_rmwsrf_rider", "id")
            )
            self.assertFKExists(
                "test_rmwsrf_horserider",
                ["friend_id"],
                ("test_rmwsrf_horserider", "id"),
            )
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_rmwsrf", editor, new_state, project_state
            )
        self.assertTableExists("test_rmwsrf_rider")
        self.assertTableNotExists("test_rmwsrf_horserider")
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                "test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_rider", "id")
            )
            self.assertFKNotExists(
                "test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_horserider", "id")
            )

    def test_rename_model_with_superclass_fk(self):
        
        project_state = self.set_up_test_model(
            "test_rmwsc", related_model=True, mti_model=True
        )
        
        operation = migrations.RenameModel("ShetlandPony", "LittleHorse")
        self.assertEqual(
            operation.describe(), "Rename model ShetlandPony to LittleHorse"
        )
        new_state = project_state.clone()
        operation.state_forwards("test_rmwsc", new_state)
        self.assertNotIn(("test_rmwsc", "shetlandpony"), new_state.models)
        self.assertIn(("test_rmwsc", "littlehorse"), new_state.models)
        
        self.assertEqual(
            project_state.models["test_rmwsc", "rider"]
            .fields["pony"]
            .remote_field.model,
            new_state.models["test_rmwsc", "rider"].fields["pony"].remote_field.model,
        )
        
        
        self.assertTableExists("test_rmwsc_shetlandpony")
        self.assertTableNotExists("test_rmwsc_littlehorse")
        if connection.features.supports_foreign_keys:
            
            self.assertFKExists(
                "test_rmwsc_rider", ["pony_id"], ("test_rmwsc_pony", "id")
            )
            self.assertFKNotExists(
                "test_rmwsc_rider", ["pony_id"], ("test_rmwsc_shetlandpony", "id")
            )
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rmwsc", editor, project_state, new_state)
        
        self.assertTableNotExists("test_rmwsc_shetlandpony")
        self.assertTableExists("test_rmwsc_littlehorse")
        if connection.features.supports_foreign_keys:
            
            self.assertFKExists(
                "test_rmwsc_rider", ["pony_id"], ("test_rmwsc_pony", "id")
            )
            self.assertFKNotExists(
                "test_rmwsc_rider", ["pony_id"], ("test_rmwsc_littlehorse", "id")
            )

    def test_rename_model_no_relations_with_db_table_noop(self):
        app_label = "test_rmwdbtnoop"
        project_state = self.set_up_test_model(app_label, db_table="my_pony")
        operation = migrations.RenameModel("Pony", "LittleHorse")
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor, self.assertNumQueries(0):
            operation.database_forwards(app_label, editor, project_state, new_state)

    @skipUnlessDBFeature("supports_foreign_keys")
    def test_rename_model_with_db_table_and_fk_noop(self):
        app_label = "test_rmwdbtfk"
        project_state = self.set_up_test_model(
            app_label, db_table="my_pony", related_model=True
        )
        new_state = project_state.clone()
        operation = migrations.RenameModel("Pony", "LittleHorse")
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor, self.assertNumQueries(0):
            operation.database_forwards(app_label, editor, project_state, new_state)

    def test_rename_model_with_self_referential_m2m(self):
        app_label = "test_rename_model_with_self_referential_m2m"

        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "ReflexivePony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("ponies", models.ManyToManyField("self")),
                    ],
                ),
            ],
        )
        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.RenameModel("ReflexivePony", "ReflexivePony2"),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "ReflexivePony2")
        pony = Pony.objects.create()
        pony.ponies.add(pony)

    def test_rename_model_with_m2m(self):
        app_label = "test_rename_model_with_m2m"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("riders", models.ManyToManyField("Rider")),
                    ],
                ),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony")
        Rider = project_state.apps.get_model(app_label, "Rider")
        pony = Pony.objects.create()
        rider = Rider.objects.create()
        pony.riders.add(rider)

        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.RenameModel("Pony", "Pony2"),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony2")
        Rider = project_state.apps.get_model(app_label, "Rider")
        pony = Pony.objects.create()
        rider = Rider.objects.create()
        pony.riders.add(rider)
        self.assertEqual(Pony.objects.count(), 2)
        self.assertEqual(Rider.objects.count(), 2)
        self.assertEqual(
            Pony._meta.get_field("riders").remote_field.through.objects.count(), 2
        )

    def test_rename_model_with_m2m_models_in_different_apps_with_same_name(self):
        app_label_1 = "test_rmw_m2m_1"
        app_label_2 = "test_rmw_m2m_2"
        project_state = self.apply_operations(
            app_label_1,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
            ],
        )
        project_state = self.apply_operations(
            app_label_2,
            project_state,
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("riders", models.ManyToManyField(f"{app_label_1}.Rider")),
                    ],
                ),
            ],
        )
        m2m_table = f"{app_label_2}_rider_riders"
        self.assertColumnExists(m2m_table, "from_rider_id")
        self.assertColumnExists(m2m_table, "to_rider_id")

        Rider_1 = project_state.apps.get_model(app_label_1, "Rider")
        Rider_2 = project_state.apps.get_model(app_label_2, "Rider")
        rider_2 = Rider_2.objects.create()
        rider_2.riders.add(Rider_1.objects.create())
        
        project_state_2 = project_state.clone()
        project_state = self.apply_operations(
            app_label_2,
            project_state,
            operations=[migrations.RenameModel("Rider", "Pony")],
        )

        m2m_table = f"{app_label_2}_pony_riders"
        self.assertColumnExists(m2m_table, "pony_id")
        self.assertColumnExists(m2m_table, "rider_id")

        Rider_1 = project_state.apps.get_model(app_label_1, "Rider")
        Rider_2 = project_state.apps.get_model(app_label_2, "Pony")
        rider_2 = Rider_2.objects.create()
        rider_2.riders.add(Rider_1.objects.create())
        self.assertEqual(Rider_1.objects.count(), 2)
        self.assertEqual(Rider_2.objects.count(), 2)
        self.assertEqual(
            Rider_2._meta.get_field("riders").remote_field.through.objects.count(), 2
        )
        
        self.unapply_operations(
            app_label_2,
            project_state_2,
            operations=[migrations.RenameModel("Rider", "Pony")],
        )
        m2m_table = f"{app_label_2}_rider_riders"
        self.assertColumnExists(m2m_table, "to_rider_id")
        self.assertColumnExists(m2m_table, "from_rider_id")

    def test_rename_model_with_db_table_rename_m2m(self):
        app_label = "test_rmwdbrm2m"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("riders", models.ManyToManyField("Rider")),
                    ],
                    options={"db_table": "pony"},
                ),
            ],
        )
        new_state = self.apply_operations(
            app_label,
            project_state,
            operations=[migrations.RenameModel("Pony", "PinkPony")],
        )
        Pony = new_state.apps.get_model(app_label, "PinkPony")
        Rider = new_state.apps.get_model(app_label, "Rider")
        pony = Pony.objects.create()
        rider = Rider.objects.create()
        pony.riders.add(rider)

    def test_rename_m2m_target_model(self):
        app_label = "test_rename_m2m_target_model"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("riders", models.ManyToManyField("Rider")),
                    ],
                ),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony")
        Rider = project_state.apps.get_model(app_label, "Rider")
        pony = Pony.objects.create()
        rider = Rider.objects.create()
        pony.riders.add(rider)

        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.RenameModel("Rider", "Rider2"),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony")
        Rider = project_state.apps.get_model(app_label, "Rider2")
        pony = Pony.objects.create()
        rider = Rider.objects.create()
        pony.riders.add(rider)
        self.assertEqual(Pony.objects.count(), 2)
        self.assertEqual(Rider.objects.count(), 2)
        self.assertEqual(
            Pony._meta.get_field("riders").remote_field.through.objects.count(), 2
        )

    def test_rename_m2m_through_model(self):
        app_label = "test_rename_through"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
                migrations.CreateModel(
                    "PonyRider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "rider",
                            models.ForeignKey(
                                "test_rename_through.Rider", models.CASCADE
                            ),
                        ),
                        (
                            "pony",
                            models.ForeignKey(
                                "test_rename_through.Pony", models.CASCADE
                            ),
                        ),
                    ],
                ),
                migrations.AddField(
                    "Pony",
                    "riders",
                    models.ManyToManyField(
                        "test_rename_through.Rider",
                        through="test_rename_through.PonyRider",
                    ),
                ),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony")
        Rider = project_state.apps.get_model(app_label, "Rider")
        PonyRider = project_state.apps.get_model(app_label, "PonyRider")
        pony = Pony.objects.create()
        rider = Rider.objects.create()
        PonyRider.objects.create(pony=pony, rider=rider)

        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.RenameModel("PonyRider", "PonyRider2"),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony")
        Rider = project_state.apps.get_model(app_label, "Rider")
        PonyRider = project_state.apps.get_model(app_label, "PonyRider2")
        pony = Pony.objects.first()
        rider = Rider.objects.create()
        PonyRider.objects.create(pony=pony, rider=rider)
        self.assertEqual(Pony.objects.count(), 1)
        self.assertEqual(Rider.objects.count(), 2)
        self.assertEqual(PonyRider.objects.count(), 2)
        self.assertEqual(pony.riders.count(), 2)

    def test_rename_m2m_model_after_rename_field(self):
        
        app_label = "test_rename_multiple"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("name", models.CharField(max_length=20)),
                    ],
                ),
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "pony",
                            models.ForeignKey(
                                "test_rename_multiple.Pony", models.CASCADE
                            ),
                        ),
                    ],
                ),
                migrations.CreateModel(
                    "PonyRider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("riders", models.ManyToManyField("Rider")),
                    ],
                ),
                migrations.RenameField(
                    model_name="pony", old_name="name", new_name="fancy_name"
                ),
                migrations.RenameModel(old_name="Rider", new_name="Jockey"),
            ],
        )
        Pony = project_state.apps.get_model(app_label, "Pony")
        Jockey = project_state.apps.get_model(app_label, "Jockey")
        PonyRider = project_state.apps.get_model(app_label, "PonyRider")
        
        pony = Pony.objects.create(fancy_name="a good name")
        jockey = Jockey.objects.create(pony=pony)
        ponyrider = PonyRider.objects.create()
        ponyrider.riders.add(jockey)

    def test_add_field(self):
        
        
        operation = migrations.AddField(
            "Pony",
            "height",
            models.FloatField(null=True, default=5),
        )
        self.assertEqual(operation.describe(), "Add field height to Pony")
        self.assertEqual(operation.migration_name_fragment, "pony_height")
        project_state, new_state = self.make_test_state("test_adfl", operation)
        self.assertEqual(len(new_state.models["test_adfl", "pony"].fields), 6)
        field = new_state.models["test_adfl", "pony"].fields["height"]
        self.assertEqual(field.default, 5)
        
        self.assertColumnNotExists("test_adfl_pony", "height")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_adfl", editor, project_state, new_state)
        self.assertColumnExists("test_adfl_pony", "height")
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_adfl", editor, new_state, project_state)
        self.assertColumnNotExists("test_adfl_pony", "height")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddField")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["field", "model_name", "name"])

    def test_add_charfield(self):
        
        project_state = self.set_up_test_model("test_adchfl")

        Pony = project_state.apps.get_model("test_adchfl", "Pony")
        pony = Pony.objects.create(weight=42)

        new_state = self.apply_operations(
            "test_adchfl",
            project_state,
            [
                migrations.AddField(
                    "Pony",
                    "text",
                    models.CharField(max_length=10, default="some text"),
                ),
                migrations.AddField(
                    "Pony",
                    "empty",
                    models.CharField(max_length=10, default=""),
                ),
                
                migrations.AddField(
                    "Pony",
                    "digits",
                    models.CharField(max_length=10, default="42"),
                ),
                
                migrations.AddField(
                    "Pony",
                    "quotes",
                    models.CharField(max_length=10, default='"\'"'),
                ),
            ],
        )

        Pony = new_state.apps.get_model("test_adchfl", "Pony")
        pony = Pony.objects.get(pk=pony.pk)
        self.assertEqual(pony.text, "some text")
        self.assertEqual(pony.empty, "")
        self.assertEqual(pony.digits, "42")
        self.assertEqual(pony.quotes, '"\'"')

    def test_add_textfield(self):
        
        project_state = self.set_up_test_model("test_adtxtfl")

        Pony = project_state.apps.get_model("test_adtxtfl", "Pony")
        pony = Pony.objects.create(weight=42)

        new_state = self.apply_operations(
            "test_adtxtfl",
            project_state,
            [
                migrations.AddField(
                    "Pony",
                    "text",
                    models.TextField(default="some text"),
                ),
                migrations.AddField(
                    "Pony",
                    "empty",
                    models.TextField(default=""),
                ),
                
                migrations.AddField(
                    "Pony",
                    "digits",
                    models.TextField(default="42"),
                ),
                
                migrations.AddField(
                    "Pony",
                    "quotes",
                    models.TextField(default='"\'"'),
                ),
            ],
        )

        Pony = new_state.apps.get_model("test_adtxtfl", "Pony")
        pony = Pony.objects.get(pk=pony.pk)
        self.assertEqual(pony.text, "some text")
        self.assertEqual(pony.empty, "")
        self.assertEqual(pony.digits, "42")
        self.assertEqual(pony.quotes, '"\'"')

    def test_add_binaryfield(self):
        
        project_state = self.set_up_test_model("test_adbinfl")

        Pony = project_state.apps.get_model("test_adbinfl", "Pony")
        pony = Pony.objects.create(weight=42)

        new_state = self.apply_operations(
            "test_adbinfl",
            project_state,
            [
                migrations.AddField(
                    "Pony",
                    "blob",
                    models.BinaryField(default=b"some text"),
                ),
                migrations.AddField(
                    "Pony",
                    "empty",
                    models.BinaryField(default=b""),
                ),
                
                migrations.AddField(
                    "Pony",
                    "digits",
                    models.BinaryField(default=b"42"),
                ),
                
                migrations.AddField(
                    "Pony",
                    "quotes",
                    models.BinaryField(default=b'"\'"'),
                ),
            ],
        )

        Pony = new_state.apps.get_model("test_adbinfl", "Pony")
        pony = Pony.objects.get(pk=pony.pk)
        
        self.assertEqual(bytes(pony.blob), b"some text")
        self.assertEqual(bytes(pony.empty), b"")
        self.assertEqual(bytes(pony.digits), b"42")
        self.assertEqual(bytes(pony.quotes), b'"\'"')

    def test_column_name_quoting(self):
        
        project_state = self.set_up_test_model("test_regr22168")
        operation = migrations.AddField(
            "Pony",
            "order",
            models.IntegerField(default=0),
        )
        new_state = project_state.clone()
        operation.state_forwards("test_regr22168", new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_regr22168", editor, project_state, new_state
            )
        self.assertColumnExists("test_regr22168_pony", "order")

    def test_add_field_preserve_default(self):
        
        project_state = self.set_up_test_model("test_adflpd")
        
        operation = migrations.AddField(
            "Pony",
            "height",
            models.FloatField(null=True, default=4),
            preserve_default=False,
        )
        new_state = project_state.clone()
        operation.state_forwards("test_adflpd", new_state)
        self.assertEqual(len(new_state.models["test_adflpd", "pony"].fields), 6)
        field = new_state.models["test_adflpd", "pony"].fields["height"]
        self.assertEqual(field.default, models.NOT_PROVIDED)
        
        project_state.apps.get_model("test_adflpd", "pony").objects.create(
            weight=4,
        )
        self.assertColumnNotExists("test_adflpd_pony", "height")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_adflpd", editor, project_state, new_state)
        self.assertColumnExists("test_adflpd_pony", "height")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddField")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            sorted(definition[2]), ["field", "model_name", "name", "preserve_default"]
        )

    def test_add_field_database_default(self):
        
        app_label = "test_adfldd"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.AddField(
            "Pony", "height", models.FloatField(null=True, db_default=4)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(len(new_state.models[app_label, "pony"].fields), 6)
        field = new_state.models[app_label, "pony"].fields["height"]
        self.assertEqual(field.default, models.NOT_PROVIDED)
        self.assertEqual(field.db_default, Value(4))
        project_state.apps.get_model(app_label, "pony").objects.create(weight=4)
        self.assertColumnNotExists(table_name, "height")
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(table_name, "height")
        new_model = new_state.apps.get_model(app_label, "pony")
        old_pony = new_model.objects.get()
        self.assertEqual(old_pony.height, 4)
        new_pony = new_model.objects.create(weight=5)
        if not connection.features.can_return_columns_from_insert:
            new_pony.refresh_from_db()
        self.assertEqual(new_pony.height, 4)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertColumnNotExists(table_name, "height")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddField")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "field": field,
                "model_name": "Pony",
                "name": "height",
            },
        )

    def test_add_field_database_default_special_char_escaping(self):
        app_label = "test_adflddsce"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        old_pony_pk = (
            project_state.apps.get_model(app_label, "pony").objects.create(weight=4).pk
        )
        tests = ["%", "'", '"']
        for db_default in tests:
            with self.subTest(db_default=db_default):
                operation = migrations.AddField(
                    "Pony",
                    "special_char",
                    models.CharField(max_length=1, db_default=db_default),
                )
                new_state = project_state.clone()
                operation.state_forwards(app_label, new_state)
                self.assertEqual(len(new_state.models[app_label, "pony"].fields), 6)
                field = new_state.models[app_label, "pony"].fields["special_char"]
                self.assertEqual(field.default, models.NOT_PROVIDED)
                self.assertEqual(field.db_default, Value(db_default))
                self.assertColumnNotExists(table_name, "special_char")
                with connection.schema_editor() as editor:
                    operation.database_forwards(
                        app_label, editor, project_state, new_state
                    )
                self.assertColumnExists(table_name, "special_char")
                new_model = new_state.apps.get_model(app_label, "pony")
                try:
                    new_pony = new_model.objects.create(weight=5)
                    if not connection.features.can_return_columns_from_insert:
                        new_pony.refresh_from_db()
                    self.assertEqual(new_pony.special_char, db_default)

                    old_pony = new_model.objects.get(pk=old_pony_pk)
                    if connection.vendor != "oracle" or db_default != "'":
                        
                        
                        
                        
                        self.assertEqual(old_pony.special_char, db_default)
                finally:
                    with connection.schema_editor() as editor:
                        operation.database_backwards(
                            app_label, editor, new_state, project_state
                        )

    @skipUnlessDBFeature("supports_expression_defaults")
    def test_add_field_database_default_function(self):
        app_label = "test_adflddf"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.AddField(
            "Pony", "height", models.FloatField(db_default=Pi())
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(len(new_state.models[app_label, "pony"].fields), 6)
        field = new_state.models[app_label, "pony"].fields["height"]
        self.assertEqual(field.default, models.NOT_PROVIDED)
        self.assertEqual(field.db_default, Pi())
        project_state.apps.get_model(app_label, "pony").objects.create(weight=4)
        self.assertColumnNotExists(table_name, "height")
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(table_name, "height")
        new_model = new_state.apps.get_model(app_label, "pony")
        old_pony = new_model.objects.get()
        self.assertAlmostEqual(old_pony.height, math.pi)
        new_pony = new_model.objects.create(weight=5)
        if not connection.features.can_return_columns_from_insert:
            new_pony.refresh_from_db()
        self.assertAlmostEqual(old_pony.height, math.pi)

    def test_add_field_both_defaults(self):
        
        app_label = "test_adflbddd"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.AddField(
            "Pony", "height", models.FloatField(default=3, db_default=4)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(len(new_state.models[app_label, "pony"].fields), 6)
        field = new_state.models[app_label, "pony"].fields["height"]
        self.assertEqual(field.default, 3)
        self.assertEqual(field.db_default, Value(4))
        pre_pony_pk = (
            project_state.apps.get_model(app_label, "pony").objects.create(weight=4).pk
        )
        self.assertColumnNotExists(table_name, "height")
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(table_name, "height")
        post_pony_pk = (
            project_state.apps.get_model(app_label, "pony").objects.create(weight=10).pk
        )
        new_model = new_state.apps.get_model(app_label, "pony")
        pre_pony = new_model.objects.get(pk=pre_pony_pk)
        self.assertEqual(pre_pony.height, 4)
        post_pony = new_model.objects.get(pk=post_pony_pk)
        self.assertEqual(post_pony.height, 4)
        new_pony = new_model.objects.create(weight=5)
        if not connection.features.can_return_columns_from_insert:
            new_pony.refresh_from_db()
        self.assertEqual(new_pony.height, 3)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertColumnNotExists(table_name, "height")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddField")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "field": field,
                "model_name": "Pony",
                "name": "height",
            },
        )

    def test_add_field_m2m(self):
        
        project_state = self.set_up_test_model("test_adflmm", second_model=True)
        
        operation = migrations.AddField(
            "Pony", "stables", models.ManyToManyField("Stable", related_name="ponies")
        )
        new_state = project_state.clone()
        operation.state_forwards("test_adflmm", new_state)
        self.assertEqual(len(new_state.models["test_adflmm", "pony"].fields), 6)
        
        self.assertTableNotExists("test_adflmm_pony_stables")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_adflmm", editor, project_state, new_state)
        self.assertTableExists("test_adflmm_pony_stables")
        self.assertColumnNotExists("test_adflmm_pony", "stables")
        
        with atomic():
            Pony = new_state.apps.get_model("test_adflmm", "Pony")
            p = Pony.objects.create(pink=False, weight=4.55)
            p.stables.create()
            self.assertEqual(p.stables.count(), 1)
            p.stables.all().delete()
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_adflmm", editor, new_state, project_state
            )
        self.assertTableNotExists("test_adflmm_pony_stables")

    def test_alter_field_m2m(self):
        project_state = self.set_up_test_model("test_alflmm", second_model=True)

        project_state = self.apply_operations(
            "test_alflmm",
            project_state,
            operations=[
                migrations.AddField(
                    "Pony",
                    "stables",
                    models.ManyToManyField("Stable", related_name="ponies"),
                )
            ],
        )
        Pony = project_state.apps.get_model("test_alflmm", "Pony")
        self.assertFalse(Pony._meta.get_field("stables").blank)

        project_state = self.apply_operations(
            "test_alflmm",
            project_state,
            operations=[
                migrations.AlterField(
                    "Pony",
                    "stables",
                    models.ManyToManyField(
                        to="Stable", related_name="ponies", blank=True
                    ),
                )
            ],
        )
        Pony = project_state.apps.get_model("test_alflmm", "Pony")
        self.assertTrue(Pony._meta.get_field("stables").blank)

    def test_repoint_field_m2m(self):
        project_state = self.set_up_test_model(
            "test_alflmm", second_model=True, third_model=True
        )

        project_state = self.apply_operations(
            "test_alflmm",
            project_state,
            operations=[
                migrations.AddField(
                    "Pony",
                    "places",
                    models.ManyToManyField("Stable", related_name="ponies"),
                )
            ],
        )
        Pony = project_state.apps.get_model("test_alflmm", "Pony")

        project_state = self.apply_operations(
            "test_alflmm",
            project_state,
            operations=[
                migrations.AlterField(
                    "Pony",
                    "places",
                    models.ManyToManyField(to="Van", related_name="ponies"),
                )
            ],
        )

        
        Pony = project_state.apps.get_model("test_alflmm", "Pony")
        p = Pony.objects.create(pink=False, weight=4.55)
        p.places.create()
        self.assertEqual(p.places.count(), 1)
        p.places.all().delete()

    def test_remove_field_m2m(self):
        project_state = self.set_up_test_model("test_rmflmm", second_model=True)

        project_state = self.apply_operations(
            "test_rmflmm",
            project_state,
            operations=[
                migrations.AddField(
                    "Pony",
                    "stables",
                    models.ManyToManyField("Stable", related_name="ponies"),
                )
            ],
        )
        self.assertTableExists("test_rmflmm_pony_stables")

        with_field_state = project_state.clone()
        operations = [migrations.RemoveField("Pony", "stables")]
        project_state = self.apply_operations(
            "test_rmflmm", project_state, operations=operations
        )
        self.assertTableNotExists("test_rmflmm_pony_stables")

        
        self.unapply_operations("test_rmflmm", with_field_state, operations=operations)
        self.assertTableExists("test_rmflmm_pony_stables")

    def test_remove_field_m2m_with_through(self):
        project_state = self.set_up_test_model("test_rmflmmwt", second_model=True)

        self.assertTableNotExists("test_rmflmmwt_ponystables")
        project_state = self.apply_operations(
            "test_rmflmmwt",
            project_state,
            operations=[
                migrations.CreateModel(
                    "PonyStables",
                    fields=[
                        (
                            "pony",
                            models.ForeignKey("test_rmflmmwt.Pony", models.CASCADE),
                        ),
                        (
                            "stable",
                            models.ForeignKey("test_rmflmmwt.Stable", models.CASCADE),
                        ),
                    ],
                ),
                migrations.AddField(
                    "Pony",
                    "stables",
                    models.ManyToManyField(
                        "Stable",
                        related_name="ponies",
                        through="test_rmflmmwt.PonyStables",
                    ),
                ),
            ],
        )
        self.assertTableExists("test_rmflmmwt_ponystables")

        operations = [
            migrations.RemoveField("Pony", "stables"),
            migrations.DeleteModel("PonyStables"),
        ]
        self.apply_operations("test_rmflmmwt", project_state, operations=operations)

    def test_remove_field(self):
        
        project_state = self.set_up_test_model("test_rmfl")
        
        operation = migrations.RemoveField("Pony", "pink")
        self.assertEqual(operation.describe(), "Remove field pink from Pony")
        self.assertEqual(operation.migration_name_fragment, "remove_pony_pink")
        new_state = project_state.clone()
        operation.state_forwards("test_rmfl", new_state)
        self.assertEqual(len(new_state.models["test_rmfl", "pony"].fields), 4)
        
        self.assertColumnExists("test_rmfl_pony", "pink")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rmfl", editor, project_state, new_state)
        self.assertColumnNotExists("test_rmfl_pony", "pink")
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_rmfl", editor, new_state, project_state)
        self.assertColumnExists("test_rmfl_pony", "pink")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RemoveField")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"model_name": "Pony", "name": "pink"})

    def test_remove_fk(self):
        
        project_state = self.set_up_test_model("test_rfk", related_model=True)
        self.assertColumnExists("test_rfk_rider", "pony_id")
        operation = migrations.RemoveField("Rider", "pony")

        new_state = project_state.clone()
        operation.state_forwards("test_rfk", new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rfk", editor, project_state, new_state)
        self.assertColumnNotExists("test_rfk_rider", "pony_id")
        with connection.schema_editor() as editor:
            operation.database_backwards("test_rfk", editor, new_state, project_state)
        self.assertColumnExists("test_rfk_rider", "pony_id")

    def test_alter_model_table(self):
        
        project_state = self.set_up_test_model("test_almota")
        
        operation = migrations.AlterModelTable("Pony", "test_almota_pony_2")
        self.assertEqual(
            operation.describe(), "Rename table for Pony to test_almota_pony_2"
        )
        self.assertEqual(operation.migration_name_fragment, "alter_pony_table")
        new_state = project_state.clone()
        operation.state_forwards("test_almota", new_state)
        self.assertEqual(
            new_state.models["test_almota", "pony"].options["db_table"],
            "test_almota_pony_2",
        )
        
        self.assertTableExists("test_almota_pony")
        self.assertTableNotExists("test_almota_pony_2")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_almota", editor, project_state, new_state)
        self.assertTableNotExists("test_almota_pony")
        self.assertTableExists("test_almota_pony_2")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_almota", editor, new_state, project_state
            )
        self.assertTableExists("test_almota_pony")
        self.assertTableNotExists("test_almota_pony_2")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterModelTable")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"name": "Pony", "table": "test_almota_pony_2"})

    def test_alter_model_table_none(self):
        
        operation = migrations.AlterModelTable("Pony", None)
        self.assertEqual(operation.describe(), "Rename table for Pony to (default)")

    def test_alter_model_table_noop(self):
        
        project_state = self.set_up_test_model("test_almota")
        
        operation = migrations.AlterModelTable("Pony", "test_almota_pony")
        new_state = project_state.clone()
        operation.state_forwards("test_almota", new_state)
        self.assertEqual(
            new_state.models["test_almota", "pony"].options["db_table"],
            "test_almota_pony",
        )
        
        self.assertTableExists("test_almota_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_almota", editor, project_state, new_state)
        self.assertTableExists("test_almota_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_almota", editor, new_state, project_state
            )
        self.assertTableExists("test_almota_pony")

    def test_alter_model_table_m2m(self):
        
        app_label = "test_talflmltlm2m"
        pony_db_table = "pony_foo"
        project_state = self.set_up_test_model(
            app_label, second_model=True, db_table=pony_db_table
        )
        
        first_state = project_state.clone()
        operation = migrations.AddField(
            "Pony", "stables", models.ManyToManyField("Stable")
        )
        operation.state_forwards(app_label, first_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, first_state)
        original_m2m_table = "%s_%s" % (pony_db_table, "stables")
        new_m2m_table = "%s_%s" % (app_label, "pony_stables")
        self.assertTableExists(original_m2m_table)
        self.assertTableNotExists(new_m2m_table)
        
        second_state = first_state.clone()
        operation = migrations.AlterModelTable(name="pony", table=None)
        operation.state_forwards(app_label, second_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, first_state, second_state)
        self.assertTableExists(new_m2m_table)
        self.assertTableNotExists(original_m2m_table)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, second_state, first_state)
        self.assertTableExists(original_m2m_table)
        self.assertTableNotExists(new_m2m_table)

    def test_alter_model_table_m2m_field(self):
        app_label = "test_talm2mfl"
        project_state = self.set_up_test_model(app_label, second_model=True)
        
        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.AddField(
                    "Pony",
                    "stables",
                    models.ManyToManyField("Stable"),
                )
            ],
        )
        m2m_table = f"{app_label}_pony_stables"
        self.assertColumnExists(m2m_table, "pony_id")
        self.assertColumnExists(m2m_table, "stable_id")
        
        with_field_state = project_state.clone()
        operations = [
            migrations.AlterField(
                model_name="Pony",
                name="stables",
                field=models.ManyToManyField("self"),
            )
        ]
        project_state = self.apply_operations(
            app_label, project_state, operations=operations
        )
        self.assertColumnExists(m2m_table, "from_pony_id")
        self.assertColumnExists(m2m_table, "to_pony_id")
        
        self.unapply_operations(app_label, with_field_state, operations=operations)
        self.assertColumnExists(m2m_table, "pony_id")
        self.assertColumnExists(m2m_table, "stable_id")

    def test_alter_field(self):
        
        project_state = self.set_up_test_model("test_alfl")
        
        operation = migrations.AlterField(
            "Pony", "pink", models.IntegerField(null=True)
        )
        self.assertEqual(operation.describe(), "Alter field pink on Pony")
        self.assertEqual(operation.migration_name_fragment, "alter_pony_pink")
        new_state = project_state.clone()
        operation.state_forwards("test_alfl", new_state)
        self.assertIs(
            project_state.models["test_alfl", "pony"].fields["pink"].null, False
        )
        self.assertIs(new_state.models["test_alfl", "pony"].fields["pink"].null, True)
        
        self.assertColumnNotNull("test_alfl_pony", "pink")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_alfl", editor, project_state, new_state)
        self.assertColumnNull("test_alfl_pony", "pink")
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_alfl", editor, new_state, project_state)
        self.assertColumnNotNull("test_alfl_pony", "pink")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterField")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["field", "model_name", "name"])

    def test_alter_field_add_database_default(self):
        app_label = "test_alfladd"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.AlterField(
            "Pony", "weight", models.FloatField(db_default=4.5)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        old_weight = project_state.models[app_label, "pony"].fields["weight"]
        self.assertIs(old_weight.db_default, models.NOT_PROVIDED)
        new_weight = new_state.models[app_label, "pony"].fields["weight"]
        self.assertEqual(new_weight.db_default, Value(4.5))
        with self.assertRaises(IntegrityError), transaction.atomic():
            project_state.apps.get_model(app_label, "pony").objects.create()
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        pony = new_state.apps.get_model(app_label, "pony").objects.create()
        if not connection.features.can_return_columns_from_insert:
            pony.refresh_from_db()
        self.assertEqual(pony.weight, 4.5)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        with self.assertRaises(IntegrityError), transaction.atomic():
            project_state.apps.get_model(app_label, "pony").objects.create()
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterField")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "field": new_weight,
                "model_name": "Pony",
                "name": "weight",
            },
        )

    def test_alter_field_change_default_to_database_default(self):
        
        app_label = "test_alflcdtdd"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.AlterField(
            "Pony", "pink", models.IntegerField(db_default=4)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        old_pink = project_state.models[app_label, "pony"].fields["pink"]
        self.assertEqual(old_pink.default, 3)
        self.assertIs(old_pink.db_default, models.NOT_PROVIDED)
        new_pink = new_state.models[app_label, "pony"].fields["pink"]
        self.assertIs(new_pink.default, models.NOT_PROVIDED)
        self.assertEqual(new_pink.db_default, Value(4))
        pony = project_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        self.assertEqual(pony.pink, 3)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        pony = new_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        if not connection.features.can_return_columns_from_insert:
            pony.refresh_from_db()
        self.assertEqual(pony.pink, 4)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        pony = project_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        self.assertEqual(pony.pink, 3)

    def test_alter_field_change_nullable_to_database_default_not_null(self):
        
        app_label = "test_alflcntddnn"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.AlterField(
            "Pony", "green", models.IntegerField(db_default=4)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        old_green = project_state.models[app_label, "pony"].fields["green"]
        self.assertIs(old_green.db_default, models.NOT_PROVIDED)
        new_green = new_state.models[app_label, "pony"].fields["green"]
        self.assertEqual(new_green.db_default, Value(4))
        old_pony = project_state.apps.get_model(app_label, "pony").objects.create(
            weight=1
        )
        self.assertIsNone(old_pony.green)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        old_pony.refresh_from_db()
        self.assertEqual(old_pony.green, 4)
        pony = new_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        if not connection.features.can_return_columns_from_insert:
            pony.refresh_from_db()
        self.assertEqual(pony.green, 4)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        pony = project_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        self.assertIsNone(pony.green)

    def test_alter_field_change_nullable_to_decimal_database_default_not_null(self):
        app_label = "test_alflcntdddn"
        project_state = self.set_up_test_model(app_label)
        operation_1 = migrations.AddField(
            "Pony",
            "height",
            models.DecimalField(null=True, max_digits=5, decimal_places=2),
        )
        operation_2 = migrations.AlterField(
            "Pony",
            "height",
            models.DecimalField(
                max_digits=5, decimal_places=2, db_default=Decimal("12.22")
            ),
        )
        table_name = f"{app_label}_pony"
        self.assertColumnNotExists(table_name, "height")
        
        new_state = project_state.clone()
        operation_1.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation_1.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(table_name, "height")
        old_pony = new_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        self.assertIsNone(old_pony.height)
        
        project_state, new_state = new_state, new_state.clone()
        operation_2.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation_2.database_forwards(app_label, editor, project_state, new_state)
        old_pony.refresh_from_db()
        self.assertEqual(old_pony.height, Decimal("12.22"))
        pony = new_state.apps.get_model(app_label, "pony").objects.create(weight=2)
        if not connection.features.can_return_columns_from_insert:
            pony.refresh_from_db()
        self.assertEqual(pony.height, Decimal("12.22"))

    @skipIfDBFeature("interprets_empty_strings_as_nulls")
    def test_alter_field_change_blank_nullable_database_default_to_not_null(self):
        app_label = "test_alflcbnddnn"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        default = "Yellow"
        operation = migrations.AlterField(
            "Pony",
            "yellow",
            models.CharField(blank=True, db_default=default, max_length=20),
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertColumnNull(table_name, "yellow")
        pony = project_state.apps.get_model(app_label, "pony").objects.create(
            weight=1, yellow=None
        )
        self.assertIsNone(pony.yellow)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnNotNull(table_name, "yellow")
        pony.refresh_from_db()
        self.assertEqual(pony.yellow, default)
        pony = new_state.apps.get_model(app_label, "pony").objects.create(weight=1)
        if not connection.features.can_return_columns_from_insert:
            pony.refresh_from_db()
        self.assertEqual(pony.yellow, default)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertColumnNull(table_name, "yellow")
        pony = project_state.apps.get_model(app_label, "pony").objects.create(
            weight=1, yellow=None
        )
        self.assertIsNone(pony.yellow)

    def test_alter_field_add_db_column_noop(self):
        
        app_label = "test_afadbn"
        project_state = self.set_up_test_model(app_label, related_model=True)
        pony_table = "%s_pony" % app_label
        new_state = project_state.clone()
        operation = migrations.AlterField(
            "Pony", "weight", models.FloatField(db_column="weight")
        )
        operation.state_forwards(app_label, new_state)
        self.assertIsNone(
            project_state.models[app_label, "pony"].fields["weight"].db_column,
        )
        self.assertEqual(
            new_state.models[app_label, "pony"].fields["weight"].db_column,
            "weight",
        )
        self.assertColumnExists(pony_table, "weight")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(pony_table, "weight")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_backwards(
                    app_label, editor, new_state, project_state
                )
        self.assertColumnExists(pony_table, "weight")

        rider_table = "%s_rider" % app_label
        new_state = project_state.clone()
        operation = migrations.AlterField(
            "Rider",
            "pony",
            models.ForeignKey("Pony", models.CASCADE, db_column="pony_id"),
        )
        operation.state_forwards(app_label, new_state)
        self.assertIsNone(
            project_state.models[app_label, "rider"].fields["pony"].db_column,
        )
        self.assertIs(
            new_state.models[app_label, "rider"].fields["pony"].db_column,
            "pony_id",
        )
        self.assertColumnExists(rider_table, "pony_id")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(rider_table, "pony_id")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_forwards(app_label, editor, new_state, project_state)
        self.assertColumnExists(rider_table, "pony_id")

    def test_alter_field_foreignobject_noop(self):
        app_label = "test_alflfo_noop"
        project_state = self.set_up_test_model(app_label)
        project_state = self.apply_operations(
            app_label,
            project_state,
            [
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("pony_id", models.IntegerField()),
                        (
                            "pony",
                            models.ForeignObject(
                                f"{app_label}.Pony",
                                models.CASCADE,
                                from_fields=("pony_id",),
                                to_fields=("id",),
                            ),
                        ),
                    ],
                ),
            ],
        )
        operation = migrations.AlterField(
            "Rider",
            "pony",
            models.ForeignObject(
                f"{app_label}.Pony",
                models.CASCADE,
                from_fields=("pony_id",),
                to_fields=("id",),
                null=True,
            ),
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        with (
            CaptureQueriesContext(connection) as ctx,
            connection.schema_editor() as editor,
        ):
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertIs(
            any("ALTER" in query["sql"] for query in ctx.captured_queries), False
        )

    @skipUnlessDBFeature("supports_comments")
    def test_alter_model_table_comment(self):
        app_label = "test_almotaco"
        project_state = self.set_up_test_model(app_label)
        pony_table = f"{app_label}_pony"
        
        operation = migrations.AlterModelTableComment("Pony", "Custom pony comment")
        self.assertEqual(operation.describe(), "Alter Pony table comment")
        self.assertEqual(operation.migration_name_fragment, "alter_pony_table_comment")
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            new_state.models[app_label, "pony"].options["db_table_comment"],
            "Custom pony comment",
        )
        self.assertTableCommentNotExists(pony_table)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertTableComment(pony_table, "Custom pony comment")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertTableCommentNotExists(pony_table)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterModelTableComment")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2], {"name": "Pony", "table_comment": "Custom pony comment"}
        )

    def test_alter_field_pk(self):
        
        project_state = self.set_up_test_model("test_alflpk")
        
        operation = migrations.AlterField(
            "Pony", "id", models.IntegerField(primary_key=True)
        )
        new_state = project_state.clone()
        operation.state_forwards("test_alflpk", new_state)
        self.assertIsInstance(
            project_state.models["test_alflpk", "pony"].fields["id"],
            models.AutoField,
        )
        self.assertIsInstance(
            new_state.models["test_alflpk", "pony"].fields["id"],
            models.IntegerField,
        )
        
        with connection.schema_editor() as editor:
            operation.database_forwards("test_alflpk", editor, project_state, new_state)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_alflpk", editor, new_state, project_state
            )

    @skipUnlessDBFeature("supports_foreign_keys")
    def test_alter_field_pk_fk(self):
        
        project_state = self.set_up_test_model("test_alflpkfk", related_model=True)
        project_state = self.apply_operations(
            "test_alflpkfk",
            project_state,
            [
                migrations.CreateModel(
                    "Stable",
                    fields=[
                        ("ponies", models.ManyToManyField("Pony")),
                    ],
                ),
                migrations.AddField(
                    "Pony",
                    "stables",
                    models.ManyToManyField("Stable"),
                ),
            ],
        )
        
        operation = migrations.AlterField(
            "Pony", "id", models.FloatField(primary_key=True)
        )
        new_state = project_state.clone()
        operation.state_forwards("test_alflpkfk", new_state)
        self.assertIsInstance(
            project_state.models["test_alflpkfk", "pony"].fields["id"],
            models.AutoField,
        )
        self.assertIsInstance(
            new_state.models["test_alflpkfk", "pony"].fields["id"],
            models.FloatField,
        )

        def assertIdTypeEqualsFkType():
            with connection.cursor() as cursor:
                id_type, id_null = [
                    (c.type_code, c.null_ok)
                    for c in connection.introspection.get_table_description(
                        cursor, "test_alflpkfk_pony"
                    )
                    if c.name == "id"
                ][0]
                fk_type, fk_null = [
                    (c.type_code, c.null_ok)
                    for c in connection.introspection.get_table_description(
                        cursor, "test_alflpkfk_rider"
                    )
                    if c.name == "pony_id"
                ][0]
                m2m_fk_type, m2m_fk_null = [
                    (c.type_code, c.null_ok)
                    for c in connection.introspection.get_table_description(
                        cursor,
                        "test_alflpkfk_pony_stables",
                    )
                    if c.name == "pony_id"
                ][0]
                remote_m2m_fk_type, remote_m2m_fk_null = [
                    (c.type_code, c.null_ok)
                    for c in connection.introspection.get_table_description(
                        cursor,
                        "test_alflpkfk_stable_ponies",
                    )
                    if c.name == "pony_id"
                ][0]
            self.assertEqual(id_type, fk_type)
            self.assertEqual(id_type, m2m_fk_type)
            self.assertEqual(id_type, remote_m2m_fk_type)
            self.assertEqual(id_null, fk_null)
            self.assertEqual(id_null, m2m_fk_null)
            self.assertEqual(id_null, remote_m2m_fk_null)

        assertIdTypeEqualsFkType()
        
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_alflpkfk", editor, project_state, new_state
            )
        assertIdTypeEqualsFkType()
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                "test_alflpkfk_pony_stables",
                ["pony_id"],
                ("test_alflpkfk_pony", "id"),
            )
            self.assertFKExists(
                "test_alflpkfk_stable_ponies",
                ["pony_id"],
                ("test_alflpkfk_pony", "id"),
            )
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_alflpkfk", editor, new_state, project_state
            )
        assertIdTypeEqualsFkType()
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                "test_alflpkfk_pony_stables",
                ["pony_id"],
                ("test_alflpkfk_pony", "id"),
            )
            self.assertFKExists(
                "test_alflpkfk_stable_ponies",
                ["pony_id"],
                ("test_alflpkfk_pony", "id"),
            )

    @skipUnlessDBFeature("supports_collation_on_charfield", "supports_foreign_keys")
    def test_alter_field_pk_fk_db_collation(self):
        
        collation = connection.features.test_collations.get("non_default")
        if not collation:
            self.skipTest("Language collations are not supported.")

        app_label = "test_alflpkfkdbc"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            [
                migrations.CreateModel(
                    "Pony",
                    [
                        ("id", models.CharField(primary_key=True, max_length=10)),
                    ],
                ),
                migrations.CreateModel(
                    "Rider",
                    [
                        ("pony", models.ForeignKey("Pony", models.CASCADE)),
                    ],
                ),
                migrations.CreateModel(
                    "Stable",
                    [
                        ("ponies", models.ManyToManyField("Pony")),
                    ],
                ),
            ],
        )
        
        operation = migrations.AlterField(
            "Pony",
            "id",
            models.CharField(
                primary_key=True,
                max_length=10,
                db_collation=collation,
            ),
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnCollation(f"{app_label}_pony", "id", collation)
        self.assertColumnCollation(f"{app_label}_rider", "pony_id", collation)
        self.assertColumnCollation(f"{app_label}_stable_ponies", "pony_id", collation)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)

    def test_alter_field_pk_mti_fk(self):
        app_label = "test_alflpkmtifk"
        project_state = self.set_up_test_model(app_label, mti_model=True)
        project_state = self.apply_operations(
            app_label,
            project_state,
            [
                migrations.CreateModel(
                    "ShetlandRider",
                    fields=[
                        (
                            "pony",
                            models.ForeignKey(
                                f"{app_label}.ShetlandPony", models.CASCADE
                            ),
                        ),
                    ],
                ),
            ],
        )
        operation = migrations.AlterField(
            "Pony",
            "id",
            models.BigAutoField(primary_key=True),
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertIsInstance(
            new_state.models[app_label, "pony"].fields["id"],
            models.BigAutoField,
        )

        def _get_column_id_type(cursor, table, column):
            return [
                c.type_code
                for c in connection.introspection.get_table_description(
                    cursor,
                    f"{app_label}_{table}",
                )
                if c.name == column
            ][0]

        def assertIdTypeEqualsMTIFkType():
            with connection.cursor() as cursor:
                parent_id_type = _get_column_id_type(cursor, "pony", "id")
                child_id_type = _get_column_id_type(
                    cursor, "shetlandpony", "pony_ptr_id"
                )
                mti_id_type = _get_column_id_type(cursor, "shetlandrider", "pony_id")
            self.assertEqual(parent_id_type, child_id_type)
            self.assertEqual(parent_id_type, mti_id_type)

        assertIdTypeEqualsMTIFkType()
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        assertIdTypeEqualsMTIFkType()
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                f"{app_label}_shetlandpony",
                ["pony_ptr_id"],
                (f"{app_label}_pony", "id"),
            )
            self.assertFKExists(
                f"{app_label}_shetlandrider",
                ["pony_id"],
                (f"{app_label}_shetlandpony", "pony_ptr_id"),
            )
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        assertIdTypeEqualsMTIFkType()
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                f"{app_label}_shetlandpony",
                ["pony_ptr_id"],
                (f"{app_label}_pony", "id"),
            )
            self.assertFKExists(
                f"{app_label}_shetlandrider",
                ["pony_id"],
                (f"{app_label}_shetlandpony", "pony_ptr_id"),
            )

    def test_alter_field_pk_mti_and_fk_to_base(self):
        app_label = "test_alflpkmtiftb"
        project_state = self.set_up_test_model(
            app_label,
            mti_model=True,
            related_model=True,
        )
        operation = migrations.AlterField(
            "Pony",
            "id",
            models.BigAutoField(primary_key=True),
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertIsInstance(
            new_state.models[app_label, "pony"].fields["id"],
            models.BigAutoField,
        )

        def _get_column_id_type(cursor, table, column):
            return [
                c.type_code
                for c in connection.introspection.get_table_description(
                    cursor,
                    f"{app_label}_{table}",
                )
                if c.name == column
            ][0]

        def assertIdTypeEqualsMTIFkType():
            with connection.cursor() as cursor:
                parent_id_type = _get_column_id_type(cursor, "pony", "id")
                fk_id_type = _get_column_id_type(cursor, "rider", "pony_id")
                child_id_type = _get_column_id_type(
                    cursor, "shetlandpony", "pony_ptr_id"
                )
            self.assertEqual(parent_id_type, child_id_type)
            self.assertEqual(parent_id_type, fk_id_type)

        assertIdTypeEqualsMTIFkType()
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        assertIdTypeEqualsMTIFkType()
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                f"{app_label}_shetlandpony",
                ["pony_ptr_id"],
                (f"{app_label}_pony", "id"),
            )
            self.assertFKExists(
                f"{app_label}_rider",
                ["pony_id"],
                (f"{app_label}_pony", "id"),
            )
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        assertIdTypeEqualsMTIFkType()
        if connection.features.supports_foreign_keys:
            self.assertFKExists(
                f"{app_label}_shetlandpony",
                ["pony_ptr_id"],
                (f"{app_label}_pony", "id"),
            )
            self.assertFKExists(
                f"{app_label}_rider",
                ["pony_id"],
                (f"{app_label}_pony", "id"),
            )

    @skipUnlessDBFeature("supports_foreign_keys")
    def test_alter_field_reloads_state_on_fk_with_to_field_target_type_change(self):
        app_label = "test_alflrsfkwtflttc"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("code", models.IntegerField(unique=True)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "rider",
                            models.ForeignKey(
                                "%s.Rider" % app_label, models.CASCADE, to_field="code"
                            ),
                        ),
                    ],
                ),
            ],
        )
        operation = migrations.AlterField(
            "Rider",
            "code",
            models.CharField(max_length=100, unique=True),
        )
        self.apply_operations(app_label, project_state, operations=[operation])
        id_type, id_null = [
            (c.type_code, c.null_ok)
            for c in self.get_table_description("%s_rider" % app_label)
            if c.name == "code"
        ][0]
        fk_type, fk_null = [
            (c.type_code, c.null_ok)
            for c in self.get_table_description("%s_pony" % app_label)
            if c.name == "rider_id"
        ][0]
        self.assertEqual(id_type, fk_type)
        self.assertEqual(id_null, fk_null)

    @skipUnlessDBFeature("supports_foreign_keys")
    def test_alter_field_reloads_state_fk_with_to_field_related_name_target_type_change(
        self,
    ):
        app_label = "test_alflrsfkwtflrnttc"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("code", models.PositiveIntegerField(unique=True)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "rider",
                            models.ForeignKey(
                                "%s.Rider" % app_label,
                                models.CASCADE,
                                to_field="code",
                                related_name="+",
                            ),
                        ),
                    ],
                ),
            ],
        )
        operation = migrations.AlterField(
            "Rider",
            "code",
            models.CharField(max_length=100, unique=True),
        )
        self.apply_operations(app_label, project_state, operations=[operation])

    def test_alter_field_reloads_state_on_fk_target_changes(self):
        
        app_label = "alter_alter_field_reloads_state_on_fk_target_changes"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.CharField(primary_key=True, max_length=100)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.CharField(primary_key=True, max_length=100)),
                        (
                            "rider",
                            models.ForeignKey("%s.Rider" % app_label, models.CASCADE),
                        ),
                    ],
                ),
                migrations.CreateModel(
                    "PonyRider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "pony",
                            models.ForeignKey("%s.Pony" % app_label, models.CASCADE),
                        ),
                    ],
                ),
            ],
        )
        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.AlterField(
                    "Rider", "id", models.CharField(primary_key=True, max_length=99)
                ),
                migrations.AlterField(
                    "Pony", "id", models.CharField(primary_key=True, max_length=99)
                ),
            ],
        )

    def test_alter_field_reloads_state_on_fk_with_to_field_target_changes(self):
        
        app_label = "alter_alter_field_reloads_state_on_fk_with_to_field_target_changes"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.CharField(primary_key=True, max_length=100)),
                        ("slug", models.CharField(unique=True, max_length=100)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.CharField(primary_key=True, max_length=100)),
                        (
                            "rider",
                            models.ForeignKey(
                                "%s.Rider" % app_label, models.CASCADE, to_field="slug"
                            ),
                        ),
                        ("slug", models.CharField(unique=True, max_length=100)),
                    ],
                ),
                migrations.CreateModel(
                    "PonyRider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "pony",
                            models.ForeignKey(
                                "%s.Pony" % app_label, models.CASCADE, to_field="slug"
                            ),
                        ),
                    ],
                ),
            ],
        )
        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.AlterField(
                    "Rider", "slug", models.CharField(unique=True, max_length=99)
                ),
                migrations.AlterField(
                    "Pony", "slug", models.CharField(unique=True, max_length=99)
                ),
            ],
        )

    def test_alter_field_pk_fk_char_to_int(self):
        app_label = "alter_field_pk_fk_char_to_int"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    name="Parent",
                    fields=[
                        ("id", models.CharField(max_length=255, primary_key=True)),
                    ],
                ),
                migrations.CreateModel(
                    name="Child",
                    fields=[
                        ("id", models.BigAutoField(primary_key=True)),
                        (
                            "parent",
                            models.ForeignKey(
                                f"{app_label}.Parent",
                                on_delete=models.CASCADE,
                            ),
                        ),
                    ],
                ),
            ],
        )
        self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.AlterField(
                    model_name="parent",
                    name="id",
                    field=models.BigIntegerField(primary_key=True),
                ),
            ],
        )

    def test_rename_field_reloads_state_on_fk_target_changes(self):
        
        app_label = "alter_rename_field_reloads_state_on_fk_target_changes"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Rider",
                    fields=[
                        ("id", models.CharField(primary_key=True, max_length=100)),
                    ],
                ),
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.CharField(primary_key=True, max_length=100)),
                        (
                            "rider",
                            models.ForeignKey("%s.Rider" % app_label, models.CASCADE),
                        ),
                    ],
                ),
                migrations.CreateModel(
                    "PonyRider",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        (
                            "pony",
                            models.ForeignKey("%s.Pony" % app_label, models.CASCADE),
                        ),
                    ],
                ),
            ],
        )
        project_state = self.apply_operations(
            app_label,
            project_state,
            operations=[
                migrations.RenameField("Rider", "id", "id2"),
                migrations.AlterField(
                    "Pony", "id", models.CharField(primary_key=True, max_length=99)
                ),
            ],
        )

    def test_rename_field(self):
        
        project_state = self.set_up_test_model("test_rnfl")
        operation = migrations.RenameField("Pony", "pink", "blue")
        self.assertEqual(operation.describe(), "Rename field pink on Pony to blue")
        self.assertEqual(operation.migration_name_fragment, "rename_pink_pony_blue")
        new_state = project_state.clone()
        operation.state_forwards("test_rnfl", new_state)
        self.assertIn("blue", new_state.models["test_rnfl", "pony"].fields)
        self.assertNotIn("pink", new_state.models["test_rnfl", "pony"].fields)
        
        self.assertColumnExists("test_rnfl_pony", "pink")
        self.assertColumnNotExists("test_rnfl_pony", "blue")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rnfl", editor, project_state, new_state)
        self.assertColumnExists("test_rnfl_pony", "blue")
        self.assertColumnNotExists("test_rnfl_pony", "pink")
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_rnfl", editor, new_state, project_state)
        self.assertColumnExists("test_rnfl_pony", "pink")
        self.assertColumnNotExists("test_rnfl_pony", "blue")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RenameField")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"model_name": "Pony", "old_name": "pink", "new_name": "blue"},
        )

    def test_rename_field_unique_together(self):
        project_state = self.set_up_test_model("test_rnflut", unique_together=True)
        operation = migrations.RenameField("Pony", "pink", "blue")
        new_state = project_state.clone()
        operation.state_forwards("test_rnflut", new_state)
        
        self.assertIn(
            "blue",
            new_state.models["test_rnflut", "pony"].options["unique_together"][0],
        )
        self.assertNotIn(
            "pink",
            new_state.models["test_rnflut", "pony"].options["unique_together"][0],
        )
        
        self.assertColumnExists("test_rnflut_pony", "pink")
        self.assertColumnNotExists("test_rnflut_pony", "blue")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rnflut", editor, project_state, new_state)
        self.assertColumnExists("test_rnflut_pony", "blue")
        self.assertColumnNotExists("test_rnflut_pony", "pink")
        
        with connection.cursor() as cursor:
            cursor.execute("INSERT INTO test_rnflut_pony (blue, weight) VALUES (1, 1)")
            with self.assertRaises(IntegrityError):
                with atomic():
                    cursor.execute(
                        "INSERT INTO test_rnflut_pony (blue, weight) VALUES (1, 1)"
                    )
            cursor.execute("DELETE FROM test_rnflut_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_rnflut", editor, new_state, project_state
            )
        self.assertColumnExists("test_rnflut_pony", "pink")
        self.assertColumnNotExists("test_rnflut_pony", "blue")

    def test_rename_field_with_db_column(self):
        project_state = self.apply_operations(
            "test_rfwdbc",
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("field", models.IntegerField(db_column="db_field")),
                        (
                            "fk_field",
                            models.ForeignKey(
                                "Pony",
                                models.CASCADE,
                                db_column="db_fk_field",
                            ),
                        ),
                    ],
                ),
            ],
        )
        new_state = project_state.clone()
        operation = migrations.RenameField("Pony", "field", "renamed_field")
        operation.state_forwards("test_rfwdbc", new_state)
        self.assertIn("renamed_field", new_state.models["test_rfwdbc", "pony"].fields)
        self.assertNotIn("field", new_state.models["test_rfwdbc", "pony"].fields)
        self.assertColumnExists("test_rfwdbc_pony", "db_field")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_forwards(
                    "test_rfwdbc", editor, project_state, new_state
                )
        self.assertColumnExists("test_rfwdbc_pony", "db_field")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_backwards(
                    "test_rfwdbc", editor, new_state, project_state
                )
        self.assertColumnExists("test_rfwdbc_pony", "db_field")

        new_state = project_state.clone()
        operation = migrations.RenameField("Pony", "fk_field", "renamed_fk_field")
        operation.state_forwards("test_rfwdbc", new_state)
        self.assertIn(
            "renamed_fk_field", new_state.models["test_rfwdbc", "pony"].fields
        )
        self.assertNotIn("fk_field", new_state.models["test_rfwdbc", "pony"].fields)
        self.assertColumnExists("test_rfwdbc_pony", "db_fk_field")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_forwards(
                    "test_rfwdbc", editor, project_state, new_state
                )
        self.assertColumnExists("test_rfwdbc_pony", "db_fk_field")
        with connection.schema_editor() as editor:
            with self.assertNumQueries(0):
                operation.database_backwards(
                    "test_rfwdbc", editor, new_state, project_state
                )
        self.assertColumnExists("test_rfwdbc_pony", "db_fk_field")

    def test_rename_field_case(self):
        project_state = self.apply_operations(
            "test_rfmx",
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("field", models.IntegerField()),
                    ],
                ),
            ],
        )
        new_state = project_state.clone()
        operation = migrations.RenameField("Pony", "field", "FiElD")
        operation.state_forwards("test_rfmx", new_state)
        self.assertIn("FiElD", new_state.models["test_rfmx", "pony"].fields)
        self.assertColumnExists("test_rfmx_pony", "field")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rfmx", editor, project_state, new_state)
        self.assertColumnExists(
            "test_rfmx_pony",
            connection.introspection.identifier_converter("FiElD"),
        )
        with connection.schema_editor() as editor:
            operation.database_backwards("test_rfmx", editor, new_state, project_state)
        self.assertColumnExists("test_rfmx_pony", "field")

    def test_rename_missing_field(self):
        state = ProjectState()
        state.add_model(ModelState("app", "model", []))
        with self.assertRaisesMessage(
            FieldDoesNotExist, "app.model has no field named 'field'"
        ):
            migrations.RenameField("model", "field", "new_field").state_forwards(
                "app", state
            )

    def test_rename_referenced_field_state_forward(self):
        state = ProjectState()
        state.add_model(
            ModelState(
                "app",
                "Model",
                [
                    ("id", models.AutoField(primary_key=True)),
                    ("field", models.IntegerField(unique=True)),
                ],
            )
        )
        state.add_model(
            ModelState(
                "app",
                "OtherModel",
                [
                    ("id", models.AutoField(primary_key=True)),
                    (
                        "fk",
                        models.ForeignKey("Model", models.CASCADE, to_field="field"),
                    ),
                    (
                        "fo",
                        models.ForeignObject(
                            "Model",
                            models.CASCADE,
                            from_fields=("fk",),
                            to_fields=("field",),
                        ),
                    ),
                ],
            )
        )
        operation = migrations.RenameField("Model", "field", "renamed")
        new_state = state.clone()
        operation.state_forwards("app", new_state)
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fk"].remote_field.field_name,
            "renamed",
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fk"].from_fields, ["self"]
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fk"].to_fields, ("renamed",)
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fo"].from_fields, ("fk",)
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fo"].to_fields, ("renamed",)
        )
        operation = migrations.RenameField("OtherModel", "fk", "renamed_fk")
        new_state = state.clone()
        operation.state_forwards("app", new_state)
        self.assertEqual(
            new_state.models["app", "othermodel"]
            .fields["renamed_fk"]
            .remote_field.field_name,
            "renamed",
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["renamed_fk"].from_fields,
            ("self",),
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["renamed_fk"].to_fields,
            ("renamed",),
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fo"].from_fields,
            ("renamed_fk",),
        )
        self.assertEqual(
            new_state.models["app", "othermodel"].fields["fo"].to_fields, ("renamed",)
        )

    def test_alter_unique_together(self):
        
        project_state = self.set_up_test_model("test_alunto")
        
        operation = migrations.AlterUniqueTogether("Pony", [("pink", "weight")])
        self.assertEqual(
            operation.describe(), "Alter unique_together for Pony (1 constraint(s))"
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "alter_pony_unique_together",
        )
        new_state = project_state.clone()
        operation.state_forwards("test_alunto", new_state)
        self.assertEqual(
            len(
                project_state.models["test_alunto", "pony"].options.get(
                    "unique_together", set()
                )
            ),
            0,
        )
        self.assertEqual(
            len(
                new_state.models["test_alunto", "pony"].options.get(
                    "unique_together", set()
                )
            ),
            1,
        )
        
        with connection.cursor() as cursor:
            cursor.execute("INSERT INTO test_alunto_pony (pink, weight) VALUES (1, 1)")
            cursor.execute("INSERT INTO test_alunto_pony (pink, weight) VALUES (1, 1)")
            cursor.execute("DELETE FROM test_alunto_pony")
            
            with connection.schema_editor() as editor:
                operation.database_forwards(
                    "test_alunto", editor, project_state, new_state
                )
            cursor.execute("INSERT INTO test_alunto_pony (pink, weight) VALUES (1, 1)")
            with self.assertRaises(IntegrityError):
                with atomic():
                    cursor.execute(
                        "INSERT INTO test_alunto_pony (pink, weight) VALUES (1, 1)"
                    )
            cursor.execute("DELETE FROM test_alunto_pony")
            
            with connection.schema_editor() as editor:
                operation.database_backwards(
                    "test_alunto", editor, new_state, project_state
                )
            cursor.execute("INSERT INTO test_alunto_pony (pink, weight) VALUES (1, 1)")
            cursor.execute("INSERT INTO test_alunto_pony (pink, weight) VALUES (1, 1)")
            cursor.execute("DELETE FROM test_alunto_pony")
        
        operation = migrations.AlterUniqueTogether("Pony", ("pink", "weight"))
        operation.state_forwards("test_alunto", new_state)
        self.assertEqual(
            len(
                new_state.models["test_alunto", "pony"].options.get(
                    "unique_together", set()
                )
            ),
            1,
        )
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterUniqueTogether")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2], {"name": "Pony", "unique_together": {("pink", "weight")}}
        )

    def test_alter_unique_together_remove(self):
        operation = migrations.AlterUniqueTogether("Pony", None)
        self.assertEqual(
            operation.describe(), "Alter unique_together for Pony (0 constraint(s))"
        )

    @skipUnlessDBFeature("allows_multiple_constraints_on_same_fields")
    def test_remove_unique_together_on_pk_field(self):
        app_label = "test_rutopkf"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Pony",
                    fields=[("id", models.AutoField(primary_key=True))],
                    options={"unique_together": {("id",)}},
                ),
            ],
        )
        table_name = f"{app_label}_pony"
        pk_constraint_name = f"{table_name}_pkey"
        unique_together_constraint_name = f"{table_name}_id_fb61f881_uniq"
        self.assertConstraintExists(table_name, pk_constraint_name, value=False)
        self.assertConstraintExists(
            table_name, unique_together_constraint_name, value=False
        )

        new_state = project_state.clone()
        operation = migrations.AlterUniqueTogether("Pony", set())
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertConstraintExists(table_name, pk_constraint_name, value=False)
        self.assertConstraintNotExists(table_name, unique_together_constraint_name)

    @skipUnlessDBFeature("allows_multiple_constraints_on_same_fields")
    def test_remove_unique_together_on_unique_field(self):
        app_label = "test_rutouf"
        project_state = self.apply_operations(
            app_label,
            ProjectState(),
            operations=[
                migrations.CreateModel(
                    "Pony",
                    fields=[
                        ("id", models.AutoField(primary_key=True)),
                        ("name", models.CharField(max_length=30, unique=True)),
                    ],
                    options={"unique_together": {("name",)}},
                ),
            ],
        )
        table_name = f"{app_label}_pony"
        unique_constraint_name = f"{table_name}_name_key"
        unique_together_constraint_name = f"{table_name}_name_694f3b9f_uniq"
        self.assertConstraintExists(table_name, unique_constraint_name, value=False)
        self.assertConstraintExists(
            table_name, unique_together_constraint_name, value=False
        )

        new_state = project_state.clone()
        operation = migrations.AlterUniqueTogether("Pony", set())
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertConstraintExists(table_name, unique_constraint_name, value=False)
        self.assertConstraintNotExists(table_name, unique_together_constraint_name)

    def test_add_index(self):
        
        project_state = self.set_up_test_model("test_adin")
        msg = (
            "Indexes passed to AddIndex operations require a name argument. "
            "<Index: fields=['pink']> doesn't have one."
        )
        with self.assertRaisesMessage(ValueError, msg):
            migrations.AddIndex("Pony", models.Index(fields=["pink"]))
        index = models.Index(fields=["pink"], name="test_adin_pony_pink_idx")
        operation = migrations.AddIndex("Pony", index)
        self.assertEqual(
            operation.describe(),
            "Create index test_adin_pony_pink_idx on field(s) pink of model Pony",
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "pony_test_adin_pony_pink_idx",
        )
        new_state = project_state.clone()
        operation.state_forwards("test_adin", new_state)
        
        self.assertEqual(
            len(new_state.models["test_adin", "pony"].options["indexes"]), 1
        )
        self.assertIndexNotExists("test_adin_pony", ["pink"])
        with connection.schema_editor() as editor:
            operation.database_forwards("test_adin", editor, project_state, new_state)
        self.assertIndexExists("test_adin_pony", ["pink"])
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_adin", editor, new_state, project_state)
        self.assertIndexNotExists("test_adin_pony", ["pink"])
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddIndex")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"model_name": "Pony", "index": index})

    def test_remove_index(self):
        
        project_state = self.set_up_test_model("test_rmin", multicol_index=True)
        self.assertTableExists("test_rmin_pony")
        self.assertIndexExists("test_rmin_pony", ["pink", "weight"])
        operation = migrations.RemoveIndex("Pony", "pony_test_idx")
        self.assertEqual(operation.describe(), "Remove index pony_test_idx from Pony")
        self.assertEqual(
            operation.migration_name_fragment,
            "remove_pony_pony_test_idx",
        )
        new_state = project_state.clone()
        operation.state_forwards("test_rmin", new_state)
        
        self.assertEqual(
            len(new_state.models["test_rmin", "pony"].options["indexes"]), 0
        )
        self.assertIndexExists("test_rmin_pony", ["pink", "weight"])
        
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rmin", editor, project_state, new_state)
        self.assertIndexNotExists("test_rmin_pony", ["pink", "weight"])
        
        with connection.schema_editor() as editor:
            operation.database_backwards("test_rmin", editor, new_state, project_state)
        self.assertIndexExists("test_rmin_pony", ["pink", "weight"])
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RemoveIndex")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"model_name": "Pony", "name": "pony_test_idx"})

        
        operations = [
            migrations.RemoveIndex("Pony", "pony_test_idx"),
            migrations.RemoveField("Pony", "pink"),
        ]
        self.assertColumnExists("test_rmin_pony", "pink")
        self.assertIndexExists("test_rmin_pony", ["pink", "weight"])
        
        new_state = project_state.clone()
        self.apply_operations("test_rmin", new_state, operations=operations)
        self.assertColumnNotExists("test_rmin_pony", "pink")
        self.assertIndexNotExists("test_rmin_pony", ["pink", "weight"])
        
        self.unapply_operations("test_rmin", project_state, operations=operations)
        self.assertIndexExists("test_rmin_pony", ["pink", "weight"])

    def test_rename_index(self):
        app_label = "test_rnin"
        project_state = self.set_up_test_model(app_label, index=True)
        table_name = app_label + "_pony"
        self.assertIndexNameExists(table_name, "pony_pink_idx")
        self.assertIndexNameNotExists(table_name, "new_pony_test_idx")
        operation = migrations.RenameIndex(
            "Pony", new_name="new_pony_test_idx", old_name="pony_pink_idx"
        )
        self.assertEqual(
            operation.describe(),
            "Rename index pony_pink_idx on Pony to new_pony_test_idx",
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "rename_pony_pink_idx_new_pony_test_idx",
        )

        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        
        expected_queries = 1 if connection.features.can_rename_index else 2
        with connection.schema_editor() as editor, self.assertNumQueries(
            expected_queries
        ):
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertIndexNameNotExists(table_name, "pony_pink_idx")
        self.assertIndexNameExists(table_name, "new_pony_test_idx")
        
        with connection.schema_editor() as editor, self.assertNumQueries(
            expected_queries
        ):
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertIndexNameExists(table_name, "pony_pink_idx")
        self.assertIndexNameNotExists(table_name, "new_pony_test_idx")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RenameIndex")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "model_name": "Pony",
                "old_name": "pony_pink_idx",
                "new_name": "new_pony_test_idx",
            },
        )

    def test_rename_index_arguments(self):
        msg = "RenameIndex.old_name and old_fields are mutually exclusive."
        with self.assertRaisesMessage(ValueError, msg):
            migrations.RenameIndex(
                "Pony",
                new_name="new_idx_name",
                old_name="old_idx_name",
                old_fields=("weight", "pink"),
            )
        msg = "RenameIndex requires one of old_name and old_fields arguments to be set."
        with self.assertRaisesMessage(ValueError, msg):
            migrations.RenameIndex("Pony", new_name="new_idx_name")

    def test_rename_index_unknown_unnamed_index(self):
        app_label = "test_rninuui"
        project_state = self.set_up_test_model(app_label)
        operation = migrations.RenameIndex(
            "Pony", new_name="new_pony_test_idx", old_fields=("weight", "pink")
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        msg = "Found wrong number (0) of indexes for test_rninuui_pony(weight, pink)."
        with connection.schema_editor() as editor:
            with self.assertRaisesMessage(ValueError, msg):
                operation.database_forwards(app_label, editor, project_state, new_state)

    def test_add_index_state_forwards(self):
        project_state = self.set_up_test_model("test_adinsf")
        index = models.Index(fields=["pink"], name="test_adinsf_pony_pink_idx")
        old_model = project_state.apps.get_model("test_adinsf", "Pony")
        new_state = project_state.clone()

        operation = migrations.AddIndex("Pony", index)
        operation.state_forwards("test_adinsf", new_state)
        new_model = new_state.apps.get_model("test_adinsf", "Pony")
        self.assertIsNot(old_model, new_model)

    def test_remove_index_state_forwards(self):
        project_state = self.set_up_test_model("test_rminsf")
        index = models.Index(fields=["pink"], name="test_rminsf_pony_pink_idx")
        migrations.AddIndex("Pony", index).state_forwards("test_rminsf", project_state)
        old_model = project_state.apps.get_model("test_rminsf", "Pony")
        new_state = project_state.clone()

        operation = migrations.RemoveIndex("Pony", "test_rminsf_pony_pink_idx")
        operation.state_forwards("test_rminsf", new_state)
        new_model = new_state.apps.get_model("test_rminsf", "Pony")
        self.assertIsNot(old_model, new_model)

    def test_rename_index_state_forwards(self):
        app_label = "test_rnidsf"
        project_state = self.set_up_test_model(app_label, index=True)
        old_model = project_state.apps.get_model(app_label, "Pony")
        new_state = project_state.clone()

        operation = migrations.RenameIndex(
            "Pony", new_name="new_pony_pink_idx", old_name="pony_pink_idx"
        )
        operation.state_forwards(app_label, new_state)
        new_model = new_state.apps.get_model(app_label, "Pony")
        self.assertIsNot(old_model, new_model)
        self.assertEqual(new_model._meta.indexes[0].name, "new_pony_pink_idx")

    @skipUnlessDBFeature("supports_expression_indexes")
    def test_add_func_index(self):
        app_label = "test_addfuncin"
        index_name = f"{app_label}_pony_abs_idx"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        index = models.Index(Abs("weight"), name=index_name)
        operation = migrations.AddIndex("Pony", index)
        self.assertEqual(
            operation.describe(),
            "Create index test_addfuncin_pony_abs_idx on Abs(F(weight)) on model Pony",
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "pony_test_addfuncin_pony_abs_idx",
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(len(new_state.models[app_label, "pony"].options["indexes"]), 1)
        self.assertIndexNameNotExists(table_name, index_name)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertIndexNameExists(table_name, index_name)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertIndexNameNotExists(table_name, index_name)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddIndex")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"model_name": "Pony", "index": index})

    @skipUnlessDBFeature("supports_expression_indexes")
    def test_remove_func_index(self):
        app_label = "test_rmfuncin"
        index_name = f"{app_label}_pony_abs_idx"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(
            app_label,
            indexes=[
                models.Index(Abs("weight"), name=index_name),
            ],
        )
        self.assertTableExists(table_name)
        self.assertIndexNameExists(table_name, index_name)
        operation = migrations.RemoveIndex("Pony", index_name)
        self.assertEqual(
            operation.describe(),
            "Remove index test_rmfuncin_pony_abs_idx from Pony",
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "remove_pony_test_rmfuncin_pony_abs_idx",
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(len(new_state.models[app_label, "pony"].options["indexes"]), 0)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertIndexNameNotExists(table_name, index_name)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertIndexNameExists(table_name, index_name)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RemoveIndex")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"model_name": "Pony", "name": index_name})

    @skipUnlessDBFeature("supports_expression_indexes")
    def test_alter_field_with_func_index(self):
        app_label = "test_alfuncin"
        index_name = f"{app_label}_pony_idx"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(
            app_label,
            indexes=[models.Index(Abs("pink"), name=index_name)],
        )
        operation = migrations.AlterField(
            "Pony", "pink", models.IntegerField(null=True)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertIndexNameExists(table_name, index_name)
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertIndexNameExists(table_name, index_name)

    def test_alter_field_with_index(self):
        
        project_state = self.set_up_test_model("test_alflin", index=True)
        operation = migrations.AlterField(
            "Pony", "pink", models.IntegerField(null=True)
        )
        new_state = project_state.clone()
        operation.state_forwards("test_alflin", new_state)
        
        self.assertColumnNotNull("test_alflin_pony", "pink")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_alflin", editor, project_state, new_state)
        
        self.assertIndexExists("test_alflin_pony", ["pink"])
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_alflin", editor, new_state, project_state
            )
        
        self.assertIndexExists("test_alflin_pony", ["pink"])

    def test_alter_index_together_remove(self):
        operation = migrations.AlterIndexTogether("Pony", None)
        self.assertEqual(
            operation.describe(), "Alter index_together for Pony (0 constraint(s))"
        )

    def test_add_constraint(self):
        project_state = self.set_up_test_model("test_addconstraint")
        gt_check = models.Q(pink__gt=2)
        gt_constraint = models.CheckConstraint(
            check=gt_check, name="test_add_constraint_pony_pink_gt_2"
        )
        gt_operation = migrations.AddConstraint("Pony", gt_constraint)
        self.assertEqual(
            gt_operation.describe(),
            "Create constraint test_add_constraint_pony_pink_gt_2 on model Pony",
        )
        self.assertEqual(
            gt_operation.migration_name_fragment,
            "pony_test_add_constraint_pony_pink_gt_2",
        )
        
        new_state = project_state.clone()
        gt_operation.state_forwards("test_addconstraint", new_state)
        self.assertEqual(
            len(new_state.models["test_addconstraint", "pony"].options["constraints"]),
            1,
        )
        Pony = new_state.apps.get_model("test_addconstraint", "Pony")
        self.assertEqual(len(Pony._meta.constraints), 1)
        
        with (
            CaptureQueriesContext(connection) as ctx,
            connection.schema_editor() as editor,
        ):
            gt_operation.database_forwards(
                "test_addconstraint", editor, project_state, new_state
            )
        if connection.features.supports_table_check_constraints:
            with self.assertRaises(IntegrityError), transaction.atomic():
                Pony.objects.create(pink=1, weight=1.0)
        else:
            self.assertIs(
                any("CHECK" in query["sql"] for query in ctx.captured_queries), False
            )
            Pony.objects.create(pink=1, weight=1.0)
        
        lt_check = models.Q(pink__lt=100)
        lt_constraint = models.CheckConstraint(
            check=lt_check, name="test_add_constraint_pony_pink_lt_100"
        )
        lt_operation = migrations.AddConstraint("Pony", lt_constraint)
        lt_operation.state_forwards("test_addconstraint", new_state)
        self.assertEqual(
            len(new_state.models["test_addconstraint", "pony"].options["constraints"]),
            2,
        )
        Pony = new_state.apps.get_model("test_addconstraint", "Pony")
        self.assertEqual(len(Pony._meta.constraints), 2)
        with (
            CaptureQueriesContext(connection) as ctx,
            connection.schema_editor() as editor,
        ):
            lt_operation.database_forwards(
                "test_addconstraint", editor, project_state, new_state
            )
        if connection.features.supports_table_check_constraints:
            with self.assertRaises(IntegrityError), transaction.atomic():
                Pony.objects.create(pink=100, weight=1.0)
        else:
            self.assertIs(
                any("CHECK" in query["sql"] for query in ctx.captured_queries), False
            )
            Pony.objects.create(pink=100, weight=1.0)
        
        with connection.schema_editor() as editor:
            gt_operation.database_backwards(
                "test_addconstraint", editor, new_state, project_state
            )
        Pony.objects.create(pink=1, weight=1.0)
        
        definition = gt_operation.deconstruct()
        self.assertEqual(definition[0], "AddConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2], {"model_name": "Pony", "constraint": gt_constraint}
        )

    @skipUnlessDBFeature("supports_table_check_constraints")
    def test_add_constraint_percent_escaping(self):
        app_label = "add_constraint_string_quoting"
        operations = [
            migrations.CreateModel(
                "Author",
                fields=[
                    ("id", models.AutoField(primary_key=True)),
                    ("name", models.CharField(max_length=100)),
                    ("surname", models.CharField(max_length=100, default="")),
                    ("rebate", models.CharField(max_length=100)),
                ],
            ),
        ]
        from_state = self.apply_operations(app_label, ProjectState(), operations)
        checks = [
            
            
            (
                models.Q(name__startswith="Albert"),
                {"name": "Alberta"},
                {"name": "Artur"},
            ),
            
            
            (models.Q(rebate__endswith="%"), {"rebate": "10%"}, {"rebate": "10%$"}),
            
            
            (
                ~models.Q(surname__startswith=models.F("name")),
                {"name": "Albert"},
                {"name": "Albert", "surname": "Alberto"},
            ),
            
            (
                models.Q(name="%"),
                {"name": "%"},
                {"name": "Albert"},
            ),
        ]
        for check, valid, invalid in checks:
            with self.subTest(check=check, valid=valid, invalid=invalid):
                constraint = models.CheckConstraint(check=check, name="constraint")
                operation = migrations.AddConstraint("Author", constraint)
                to_state = from_state.clone()
                operation.state_forwards(app_label, to_state)
                with connection.schema_editor() as editor:
                    operation.database_forwards(app_label, editor, from_state, to_state)
                Author = to_state.apps.get_model(app_label, "Author")
                try:
                    with transaction.atomic():
                        Author.objects.create(**valid).delete()
                    with self.assertRaises(IntegrityError), transaction.atomic():
                        Author.objects.create(**invalid)
                finally:
                    with connection.schema_editor() as editor:
                        operation.database_backwards(
                            app_label, editor, from_state, to_state
                        )

    @skipUnlessDBFeature("supports_table_check_constraints")
    def test_add_or_constraint(self):
        app_label = "test_addorconstraint"
        constraint_name = "add_constraint_or"
        from_state = self.set_up_test_model(app_label)
        check = models.Q(pink__gt=2, weight__gt=2) | models.Q(weight__lt=0)
        constraint = models.CheckConstraint(check=check, name=constraint_name)
        operation = migrations.AddConstraint("Pony", constraint)
        to_state = from_state.clone()
        operation.state_forwards(app_label, to_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, from_state, to_state)
        Pony = to_state.apps.get_model(app_label, "Pony")
        with self.assertRaises(IntegrityError), transaction.atomic():
            Pony.objects.create(pink=2, weight=3.0)
        with self.assertRaises(IntegrityError), transaction.atomic():
            Pony.objects.create(pink=3, weight=1.0)
        Pony.objects.bulk_create(
            [
                Pony(pink=3, weight=-1.0),
                Pony(pink=1, weight=-1.0),
                Pony(pink=3, weight=3.0),
            ]
        )

    @skipUnlessDBFeature("supports_table_check_constraints")
    def test_add_constraint_combinable(self):
        app_label = "test_addconstraint_combinable"
        operations = [
            migrations.CreateModel(
                "Book",
                fields=[
                    ("id", models.AutoField(primary_key=True)),
                    ("read", models.PositiveIntegerField()),
                    ("unread", models.PositiveIntegerField()),
                ],
            ),
        ]
        from_state = self.apply_operations(app_label, ProjectState(), operations)
        constraint = models.CheckConstraint(
            check=models.Q(read=(100 - models.F("unread"))),
            name="test_addconstraint_combinable_sum_100",
        )
        operation = migrations.AddConstraint("Book", constraint)
        to_state = from_state.clone()
        operation.state_forwards(app_label, to_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, from_state, to_state)
        Book = to_state.apps.get_model(app_label, "Book")
        with self.assertRaises(IntegrityError), transaction.atomic():
            Book.objects.create(read=70, unread=10)
        Book.objects.create(read=70, unread=30)

    def test_remove_constraint(self):
        project_state = self.set_up_test_model(
            "test_removeconstraint",
            constraints=[
                models.CheckConstraint(
                    check=models.Q(pink__gt=2),
                    name="test_remove_constraint_pony_pink_gt_2",
                ),
                models.CheckConstraint(
                    check=models.Q(pink__lt=100),
                    name="test_remove_constraint_pony_pink_lt_100",
                ),
            ],
        )
        gt_operation = migrations.RemoveConstraint(
            "Pony", "test_remove_constraint_pony_pink_gt_2"
        )
        self.assertEqual(
            gt_operation.describe(),
            "Remove constraint test_remove_constraint_pony_pink_gt_2 from model Pony",
        )
        self.assertEqual(
            gt_operation.migration_name_fragment,
            "remove_pony_test_remove_constraint_pony_pink_gt_2",
        )
        
        new_state = project_state.clone()
        gt_operation.state_forwards("test_removeconstraint", new_state)
        self.assertEqual(
            len(
                new_state.models["test_removeconstraint", "pony"].options["constraints"]
            ),
            1,
        )
        Pony = new_state.apps.get_model("test_removeconstraint", "Pony")
        self.assertEqual(len(Pony._meta.constraints), 1)
        
        with connection.schema_editor() as editor:
            gt_operation.database_forwards(
                "test_removeconstraint", editor, project_state, new_state
            )
        Pony.objects.create(pink=1, weight=1.0).delete()
        if connection.features.supports_table_check_constraints:
            with self.assertRaises(IntegrityError), transaction.atomic():
                Pony.objects.create(pink=100, weight=1.0)
        else:
            Pony.objects.create(pink=100, weight=1.0)
        
        lt_operation = migrations.RemoveConstraint(
            "Pony", "test_remove_constraint_pony_pink_lt_100"
        )
        lt_operation.state_forwards("test_removeconstraint", new_state)
        self.assertEqual(
            len(
                new_state.models["test_removeconstraint", "pony"].options["constraints"]
            ),
            0,
        )
        Pony = new_state.apps.get_model("test_removeconstraint", "Pony")
        self.assertEqual(len(Pony._meta.constraints), 0)
        with connection.schema_editor() as editor:
            lt_operation.database_forwards(
                "test_removeconstraint", editor, project_state, new_state
            )
        Pony.objects.create(pink=100, weight=1.0).delete()
        
        with connection.schema_editor() as editor:
            gt_operation.database_backwards(
                "test_removeconstraint", editor, new_state, project_state
            )
        if connection.features.supports_table_check_constraints:
            with self.assertRaises(IntegrityError), transaction.atomic():
                Pony.objects.create(pink=1, weight=1.0)
        else:
            Pony.objects.create(pink=1, weight=1.0)
        
        definition = gt_operation.deconstruct()
        self.assertEqual(definition[0], "RemoveConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"model_name": "Pony", "name": "test_remove_constraint_pony_pink_gt_2"},
        )

    def test_add_partial_unique_constraint(self):
        project_state = self.set_up_test_model("test_addpartialuniqueconstraint")
        partial_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            condition=models.Q(weight__gt=5),
            name="test_constraint_pony_pink_for_weight_gt_5_uniq",
        )
        operation = migrations.AddConstraint("Pony", partial_unique_constraint)
        self.assertEqual(
            operation.describe(),
            "Create constraint test_constraint_pony_pink_for_weight_gt_5_uniq "
            "on model Pony",
        )
        
        new_state = project_state.clone()
        operation.state_forwards("test_addpartialuniqueconstraint", new_state)
        self.assertEqual(
            len(
                new_state.models["test_addpartialuniqueconstraint", "pony"].options[
                    "constraints"
                ]
            ),
            1,
        )
        Pony = new_state.apps.get_model("test_addpartialuniqueconstraint", "Pony")
        self.assertEqual(len(Pony._meta.constraints), 1)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_addpartialuniqueconstraint", editor, project_state, new_state
            )
        
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=6.0)
        if connection.features.supports_partial_indexes:
            with self.assertRaises(IntegrityError), transaction.atomic():
                Pony.objects.create(pink=1, weight=7.0)
        else:
            Pony.objects.create(pink=1, weight=7.0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_addpartialuniqueconstraint", editor, new_state, project_state
            )
        
        Pony.objects.create(pink=1, weight=7.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"model_name": "Pony", "constraint": partial_unique_constraint},
        )

    def test_remove_partial_unique_constraint(self):
        project_state = self.set_up_test_model(
            "test_removepartialuniqueconstraint",
            constraints=[
                models.UniqueConstraint(
                    fields=["pink"],
                    condition=models.Q(weight__gt=5),
                    name="test_constraint_pony_pink_for_weight_gt_5_uniq",
                ),
            ],
        )
        gt_operation = migrations.RemoveConstraint(
            "Pony", "test_constraint_pony_pink_for_weight_gt_5_uniq"
        )
        self.assertEqual(
            gt_operation.describe(),
            "Remove constraint test_constraint_pony_pink_for_weight_gt_5_uniq from "
            "model Pony",
        )
        
        new_state = project_state.clone()
        gt_operation.state_forwards("test_removepartialuniqueconstraint", new_state)
        self.assertEqual(
            len(
                new_state.models["test_removepartialuniqueconstraint", "pony"].options[
                    "constraints"
                ]
            ),
            0,
        )
        Pony = new_state.apps.get_model("test_removepartialuniqueconstraint", "Pony")
        self.assertEqual(len(Pony._meta.constraints), 0)
        
        with connection.schema_editor() as editor:
            gt_operation.database_forwards(
                "test_removepartialuniqueconstraint", editor, project_state, new_state
            )
        
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=6.0)
        Pony.objects.create(pink=1, weight=7.0).delete()
        
        with connection.schema_editor() as editor:
            gt_operation.database_backwards(
                "test_removepartialuniqueconstraint", editor, new_state, project_state
            )
        
        if connection.features.supports_partial_indexes:
            with self.assertRaises(IntegrityError), transaction.atomic():
                Pony.objects.create(pink=1, weight=7.0)
        else:
            Pony.objects.create(pink=1, weight=7.0)
        
        definition = gt_operation.deconstruct()
        self.assertEqual(definition[0], "RemoveConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "model_name": "Pony",
                "name": "test_constraint_pony_pink_for_weight_gt_5_uniq",
            },
        )

    def test_add_deferred_unique_constraint(self):
        app_label = "test_adddeferred_uc"
        project_state = self.set_up_test_model(app_label)
        deferred_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            name="deferred_pink_constraint_add",
            deferrable=models.Deferrable.DEFERRED,
        )
        operation = migrations.AddConstraint("Pony", deferred_unique_constraint)
        self.assertEqual(
            operation.describe(),
            "Create constraint deferred_pink_constraint_add on model Pony",
        )
        
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            len(new_state.models[app_label, "pony"].options["constraints"]), 1
        )
        Pony = new_state.apps.get_model(app_label, "Pony")
        self.assertEqual(len(Pony._meta.constraints), 1)
        with connection.schema_editor() as editor, CaptureQueriesContext(
            connection
        ) as ctx:
            operation.database_forwards(app_label, editor, project_state, new_state)
        Pony.objects.create(pink=1, weight=4.0)
        if connection.features.supports_deferrable_unique_constraints:
            
            with transaction.atomic():
                obj = Pony.objects.create(pink=1, weight=4.0)
                obj.pink = 2
                obj.save()
            
            with self.assertRaises(IntegrityError):
                with transaction.atomic(), connection.cursor() as cursor:
                    quoted_name = connection.ops.quote_name(
                        deferred_unique_constraint.name
                    )
                    cursor.execute("SET CONSTRAINTS %s IMMEDIATE" % quoted_name)
                    obj = Pony.objects.create(pink=1, weight=4.0)
                    obj.pink = 3
                    obj.save()
        else:
            self.assertEqual(len(ctx), 0)
            Pony.objects.create(pink=1, weight=4.0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        
        Pony.objects.create(pink=1, weight=4.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"model_name": "Pony", "constraint": deferred_unique_constraint},
        )

    def test_remove_deferred_unique_constraint(self):
        app_label = "test_removedeferred_uc"
        deferred_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            name="deferred_pink_constraint_rm",
            deferrable=models.Deferrable.DEFERRED,
        )
        project_state = self.set_up_test_model(
            app_label, constraints=[deferred_unique_constraint]
        )
        operation = migrations.RemoveConstraint("Pony", deferred_unique_constraint.name)
        self.assertEqual(
            operation.describe(),
            "Remove constraint deferred_pink_constraint_rm from model Pony",
        )
        
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            len(new_state.models[app_label, "pony"].options["constraints"]), 0
        )
        Pony = new_state.apps.get_model(app_label, "Pony")
        self.assertEqual(len(Pony._meta.constraints), 0)
        with connection.schema_editor() as editor, CaptureQueriesContext(
            connection
        ) as ctx:
            operation.database_forwards(app_label, editor, project_state, new_state)
        
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=4.0).delete()
        if not connection.features.supports_deferrable_unique_constraints:
            self.assertEqual(len(ctx), 0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        if connection.features.supports_deferrable_unique_constraints:
            
            with transaction.atomic():
                obj = Pony.objects.create(pink=1, weight=4.0)
                obj.pink = 2
                obj.save()
            
            with self.assertRaises(IntegrityError):
                with transaction.atomic(), connection.cursor() as cursor:
                    quoted_name = connection.ops.quote_name(
                        deferred_unique_constraint.name
                    )
                    cursor.execute("SET CONSTRAINTS %s IMMEDIATE" % quoted_name)
                    obj = Pony.objects.create(pink=1, weight=4.0)
                    obj.pink = 3
                    obj.save()
        else:
            Pony.objects.create(pink=1, weight=4.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RemoveConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "model_name": "Pony",
                "name": "deferred_pink_constraint_rm",
            },
        )

    def test_add_covering_unique_constraint(self):
        app_label = "test_addcovering_uc"
        project_state = self.set_up_test_model(app_label)
        covering_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            name="covering_pink_constraint_add",
            include=["weight"],
        )
        operation = migrations.AddConstraint("Pony", covering_unique_constraint)
        self.assertEqual(
            operation.describe(),
            "Create constraint covering_pink_constraint_add on model Pony",
        )
        
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            len(new_state.models[app_label, "pony"].options["constraints"]), 1
        )
        Pony = new_state.apps.get_model(app_label, "Pony")
        self.assertEqual(len(Pony._meta.constraints), 1)
        with connection.schema_editor() as editor, CaptureQueriesContext(
            connection
        ) as ctx:
            operation.database_forwards(app_label, editor, project_state, new_state)
        Pony.objects.create(pink=1, weight=4.0)
        if connection.features.supports_covering_indexes:
            with self.assertRaises(IntegrityError):
                Pony.objects.create(pink=1, weight=4.0)
        else:
            self.assertEqual(len(ctx), 0)
            Pony.objects.create(pink=1, weight=4.0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        
        Pony.objects.create(pink=1, weight=4.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"model_name": "Pony", "constraint": covering_unique_constraint},
        )

    def test_remove_covering_unique_constraint(self):
        app_label = "test_removecovering_uc"
        covering_unique_constraint = models.UniqueConstraint(
            fields=["pink"],
            name="covering_pink_constraint_rm",
            include=["weight"],
        )
        project_state = self.set_up_test_model(
            app_label, constraints=[covering_unique_constraint]
        )
        operation = migrations.RemoveConstraint("Pony", covering_unique_constraint.name)
        self.assertEqual(
            operation.describe(),
            "Remove constraint covering_pink_constraint_rm from model Pony",
        )
        
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            len(new_state.models[app_label, "pony"].options["constraints"]), 0
        )
        Pony = new_state.apps.get_model(app_label, "Pony")
        self.assertEqual(len(Pony._meta.constraints), 0)
        with connection.schema_editor() as editor, CaptureQueriesContext(
            connection
        ) as ctx:
            operation.database_forwards(app_label, editor, project_state, new_state)
        
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=4.0).delete()
        if not connection.features.supports_covering_indexes:
            self.assertEqual(len(ctx), 0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        if connection.features.supports_covering_indexes:
            with self.assertRaises(IntegrityError):
                Pony.objects.create(pink=1, weight=4.0)
        else:
            Pony.objects.create(pink=1, weight=4.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RemoveConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {
                "model_name": "Pony",
                "name": "covering_pink_constraint_rm",
            },
        )

    def test_alter_field_with_func_unique_constraint(self):
        app_label = "test_alfuncuc"
        constraint_name = f"{app_label}_pony_uq"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(
            app_label,
            constraints=[
                models.UniqueConstraint("pink", "weight", name=constraint_name)
            ],
        )
        operation = migrations.AlterField(
            "Pony", "pink", models.IntegerField(null=True)
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        if connection.features.supports_expression_indexes:
            self.assertIndexNameExists(table_name, constraint_name)
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        if connection.features.supports_expression_indexes:
            self.assertIndexNameExists(table_name, constraint_name)

    def test_add_func_unique_constraint(self):
        app_label = "test_adfuncuc"
        constraint_name = f"{app_label}_pony_abs_uq"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(app_label)
        constraint = models.UniqueConstraint(Abs("weight"), name=constraint_name)
        operation = migrations.AddConstraint("Pony", constraint)
        self.assertEqual(
            operation.describe(),
            "Create constraint test_adfuncuc_pony_abs_uq on model Pony",
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "pony_test_adfuncuc_pony_abs_uq",
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            len(new_state.models[app_label, "pony"].options["constraints"]), 1
        )
        self.assertIndexNameNotExists(table_name, constraint_name)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        Pony = new_state.apps.get_model(app_label, "Pony")
        Pony.objects.create(weight=4.0)
        if connection.features.supports_expression_indexes:
            self.assertIndexNameExists(table_name, constraint_name)
            with self.assertRaises(IntegrityError):
                Pony.objects.create(weight=-4.0)
        else:
            self.assertIndexNameNotExists(table_name, constraint_name)
            Pony.objects.create(weight=-4.0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertIndexNameNotExists(table_name, constraint_name)
        
        Pony.objects.create(weight=-4.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AddConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"model_name": "Pony", "constraint": constraint},
        )

    def test_remove_func_unique_constraint(self):
        app_label = "test_rmfuncuc"
        constraint_name = f"{app_label}_pony_abs_uq"
        table_name = f"{app_label}_pony"
        project_state = self.set_up_test_model(
            app_label,
            constraints=[
                models.UniqueConstraint(Abs("weight"), name=constraint_name),
            ],
        )
        self.assertTableExists(table_name)
        if connection.features.supports_expression_indexes:
            self.assertIndexNameExists(table_name, constraint_name)
        operation = migrations.RemoveConstraint("Pony", constraint_name)
        self.assertEqual(
            operation.describe(),
            "Remove constraint test_rmfuncuc_pony_abs_uq from model Pony",
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "remove_pony_test_rmfuncuc_pony_abs_uq",
        )
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)
        self.assertEqual(
            len(new_state.models[app_label, "pony"].options["constraints"]), 0
        )
        Pony = new_state.apps.get_model(app_label, "Pony")
        self.assertEqual(len(Pony._meta.constraints), 0)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertIndexNameNotExists(table_name, constraint_name)
        
        Pony.objects.create(pink=1, weight=4.0)
        Pony.objects.create(pink=1, weight=-4.0).delete()
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        if connection.features.supports_expression_indexes:
            self.assertIndexNameExists(table_name, constraint_name)
            with self.assertRaises(IntegrityError):
                Pony.objects.create(weight=-4.0)
        else:
            self.assertIndexNameNotExists(table_name, constraint_name)
            Pony.objects.create(weight=-4.0)
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RemoveConstraint")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"model_name": "Pony", "name": constraint_name})

    def test_alter_model_options(self):
        
        project_state = self.set_up_test_model("test_almoop")
        
        operation = migrations.AlterModelOptions(
            "Pony", {"permissions": [("can_groom", "Can groom")]}
        )
        self.assertEqual(operation.describe(), "Change Meta options on Pony")
        self.assertEqual(operation.migration_name_fragment, "alter_pony_options")
        new_state = project_state.clone()
        operation.state_forwards("test_almoop", new_state)
        self.assertEqual(
            len(
                project_state.models["test_almoop", "pony"].options.get(
                    "permissions", []
                )
            ),
            0,
        )
        self.assertEqual(
            len(new_state.models["test_almoop", "pony"].options.get("permissions", [])),
            1,
        )
        self.assertEqual(
            new_state.models["test_almoop", "pony"].options["permissions"][0][0],
            "can_groom",
        )
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterModelOptions")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2],
            {"name": "Pony", "options": {"permissions": [("can_groom", "Can groom")]}},
        )

    def test_alter_model_options_emptying(self):
        
        project_state = self.set_up_test_model("test_almoop", options=True)
        
        operation = migrations.AlterModelOptions("Pony", {})
        self.assertEqual(operation.describe(), "Change Meta options on Pony")
        new_state = project_state.clone()
        operation.state_forwards("test_almoop", new_state)
        self.assertEqual(
            len(
                project_state.models["test_almoop", "pony"].options.get(
                    "permissions", []
                )
            ),
            1,
        )
        self.assertEqual(
            len(new_state.models["test_almoop", "pony"].options.get("permissions", [])),
            0,
        )
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterModelOptions")
        self.assertEqual(definition[1], [])
        self.assertEqual(definition[2], {"name": "Pony", "options": {}})

    def test_alter_order_with_respect_to(self):
        
        project_state = self.set_up_test_model("test_alorwrtto", related_model=True)
        
        operation = migrations.AlterOrderWithRespectTo("Rider", "pony")
        self.assertEqual(
            operation.describe(), "Set order_with_respect_to on Rider to pony"
        )
        self.assertEqual(
            operation.migration_name_fragment,
            "alter_rider_order_with_respect_to",
        )
        new_state = project_state.clone()
        operation.state_forwards("test_alorwrtto", new_state)
        self.assertIsNone(
            project_state.models["test_alorwrtto", "rider"].options.get(
                "order_with_respect_to", None
            )
        )
        self.assertEqual(
            new_state.models["test_alorwrtto", "rider"].options.get(
                "order_with_respect_to", None
            ),
            "pony",
        )
        
        self.assertColumnNotExists("test_alorwrtto_rider", "_order")
        
        rendered_state = project_state.apps
        pony = rendered_state.get_model("test_alorwrtto", "Pony").objects.create(
            weight=50
        )
        rider1 = rendered_state.get_model("test_alorwrtto", "Rider").objects.create(
            pony=pony
        )
        rider1.friend = rider1
        rider1.save()
        rider2 = rendered_state.get_model("test_alorwrtto", "Rider").objects.create(
            pony=pony
        )
        rider2.friend = rider2
        rider2.save()
        
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_alorwrtto", editor, project_state, new_state
            )
        self.assertColumnExists("test_alorwrtto_rider", "_order")
        
        updated_riders = new_state.apps.get_model(
            "test_alorwrtto", "Rider"
        ).objects.all()
        self.assertEqual(updated_riders[0]._order, 0)
        self.assertEqual(updated_riders[1]._order, 0)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_alorwrtto", editor, new_state, project_state
            )
        self.assertColumnNotExists("test_alorwrtto_rider", "_order")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "AlterOrderWithRespectTo")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            definition[2], {"name": "Rider", "order_with_respect_to": "pony"}
        )

    def test_alter_model_managers(self):
        
        project_state = self.set_up_test_model("test_almoma")
        
        operation = migrations.AlterModelManagers(
            "Pony",
            managers=[
                ("food_qs", FoodQuerySet.as_manager()),
                ("food_mgr", FoodManager("a", "b")),
                ("food_mgr_kwargs", FoodManager("x", "y", 3, 4)),
            ],
        )
        self.assertEqual(operation.describe(), "Change managers on Pony")
        self.assertEqual(operation.migration_name_fragment, "alter_pony_managers")
        managers = project_state.models["test_almoma", "pony"].managers
        self.assertEqual(managers, [])

        new_state = project_state.clone()
        operation.state_forwards("test_almoma", new_state)
        self.assertIn(("test_almoma", "pony"), new_state.models)
        managers = new_state.models["test_almoma", "pony"].managers
        self.assertEqual(managers[0][0], "food_qs")
        self.assertIsInstance(managers[0][1], models.Manager)
        self.assertEqual(managers[1][0], "food_mgr")
        self.assertIsInstance(managers[1][1], FoodManager)
        self.assertEqual(managers[1][1].args, ("a", "b", 1, 2))
        self.assertEqual(managers[2][0], "food_mgr_kwargs")
        self.assertIsInstance(managers[2][1], FoodManager)
        self.assertEqual(managers[2][1].args, ("x", "y", 3, 4))
        rendered_state = new_state.apps
        model = rendered_state.get_model("test_almoma", "pony")
        self.assertIsInstance(model.food_qs, models.Manager)
        self.assertIsInstance(model.food_mgr, FoodManager)
        self.assertIsInstance(model.food_mgr_kwargs, FoodManager)

    def test_alter_model_managers_emptying(self):
        
        project_state = self.set_up_test_model("test_almomae", manager_model=True)
        
        operation = migrations.AlterModelManagers("Food", managers=[])
        self.assertEqual(operation.describe(), "Change managers on Food")
        self.assertIn(("test_almomae", "food"), project_state.models)
        managers = project_state.models["test_almomae", "food"].managers
        self.assertEqual(managers[0][0], "food_qs")
        self.assertIsInstance(managers[0][1], models.Manager)
        self.assertEqual(managers[1][0], "food_mgr")
        self.assertIsInstance(managers[1][1], FoodManager)
        self.assertEqual(managers[1][1].args, ("a", "b", 1, 2))
        self.assertEqual(managers[2][0], "food_mgr_kwargs")
        self.assertIsInstance(managers[2][1], FoodManager)
        self.assertEqual(managers[2][1].args, ("x", "y", 3, 4))

        new_state = project_state.clone()
        operation.state_forwards("test_almomae", new_state)
        managers = new_state.models["test_almomae", "food"].managers
        self.assertEqual(managers, [])

    def test_alter_fk(self):
        
        project_state = self.set_up_test_model("test_alfk")
        
        create_operation = migrations.CreateModel(
            name="Rider",
            fields=[
                ("id", models.AutoField(primary_key=True)),
                ("pony", models.ForeignKey("Pony", models.CASCADE)),
            ],
        )
        create_state = project_state.clone()
        create_operation.state_forwards("test_alfk", create_state)
        alter_operation = migrations.AlterField(
            model_name="Rider",
            name="pony",
            field=models.ForeignKey("Pony", models.CASCADE, editable=False),
        )
        alter_state = create_state.clone()
        alter_operation.state_forwards("test_alfk", alter_state)
        with connection.schema_editor() as editor:
            create_operation.database_forwards(
                "test_alfk", editor, project_state, create_state
            )
            alter_operation.database_forwards(
                "test_alfk", editor, create_state, alter_state
            )

    def test_alter_fk_non_fk(self):
        
        
        operation = migrations.AlterField(
            model_name="Rider",
            name="pony",
            field=models.FloatField(),
        )
        project_state, new_state = self.make_test_state(
            "test_afknfk", operation, related_model=True
        )
        
        self.assertColumnExists("test_afknfk_rider", "pony_id")
        self.assertColumnNotExists("test_afknfk_rider", "pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_afknfk", editor, project_state, new_state)
        self.assertColumnExists("test_afknfk_rider", "pony")
        self.assertColumnNotExists("test_afknfk_rider", "pony_id")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_afknfk", editor, new_state, project_state
            )
        self.assertColumnExists("test_afknfk_rider", "pony_id")
        self.assertColumnNotExists("test_afknfk_rider", "pony")

    def test_run_sql(self):
        
        project_state = self.set_up_test_model("test_runsql")
        
        operation = migrations.RunSQL(
            
            
            "CREATE TABLE i_love_ponies (id int, special_thing varchar(15));\n"
            "INSERT INTO i_love_ponies (id, special_thing) "
            "VALUES (1, 'i love ponies'); -- this is magic!\n"
            "INSERT INTO i_love_ponies (id, special_thing) "
            "VALUES (2, 'i love django');\n"
            "UPDATE i_love_ponies SET special_thing = 'Ponies' "
            "WHERE special_thing LIKE '%%ponies';"
            "UPDATE i_love_ponies SET special_thing = 'Django' "
            "WHERE special_thing LIKE '%django';",
            
            
            "DELETE FROM i_love_ponies WHERE special_thing LIKE '%Django%';"
            "DELETE FROM i_love_ponies WHERE special_thing LIKE '%%Ponies%%';"
            "DROP TABLE i_love_ponies",
            state_operations=[
                migrations.CreateModel(
                    "SomethingElse", [("id", models.AutoField(primary_key=True))]
                )
            ],
        )
        self.assertEqual(operation.describe(), "Raw SQL operation")
        
        new_state = project_state.clone()
        operation.state_forwards("test_runsql", new_state)
        self.assertEqual(
            len(new_state.models["test_runsql", "somethingelse"].fields), 1
        )
        
        self.assertTableNotExists("i_love_ponies")
        
        with connection.schema_editor(collect_sql=True) as editor:
            operation.database_forwards("test_runsql", editor, project_state, new_state)
            self.assertIn("LIKE '%%ponies';", "\n".join(editor.collected_sql))
            operation.database_backwards(
                "test_runsql", editor, project_state, new_state
            )
            self.assertIn("LIKE '%%Ponies%%';", "\n".join(editor.collected_sql))
        
        with connection.schema_editor() as editor:
            operation.database_forwards("test_runsql", editor, project_state, new_state)
        self.assertTableExists("i_love_ponies")
        
        with connection.cursor() as cursor:
            cursor.execute("SELECT COUNT(*) FROM i_love_ponies")
            self.assertEqual(cursor.fetchall()[0][0], 2)
            cursor.execute(
                "SELECT COUNT(*) FROM i_love_ponies WHERE special_thing = 'Django'"
            )
            self.assertEqual(cursor.fetchall()[0][0], 1)
            cursor.execute(
                "SELECT COUNT(*) FROM i_love_ponies WHERE special_thing = 'Ponies'"
            )
            self.assertEqual(cursor.fetchall()[0][0], 1)
        
        self.assertTrue(operation.reversible)
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_runsql", editor, new_state, project_state
            )
        self.assertTableNotExists("i_love_ponies")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RunSQL")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            sorted(definition[2]), ["reverse_sql", "sql", "state_operations"]
        )
        
        self.assertIs(False, operation.reduce(operation, []))
        elidable_operation = migrations.RunSQL("SELECT 1 FROM void;", elidable=True)
        self.assertEqual(elidable_operation.reduce(operation, []), [operation])

    def test_run_sql_params(self):
        
        project_state = self.set_up_test_model("test_runsql")
        
        operation = migrations.RunSQL(
            ["CREATE TABLE i_love_ponies (id int, special_thing varchar(15));"],
            ["DROP TABLE i_love_ponies"],
        )
        param_operation = migrations.RunSQL(
            
            (
                "INSERT INTO i_love_ponies (id, special_thing) VALUES (1, 'Django');",
                [
                    "INSERT INTO i_love_ponies (id, special_thing) VALUES (2, %s);",
                    ["Ponies"],
                ],
                (
                    "INSERT INTO i_love_ponies (id, special_thing) VALUES (%s, %s);",
                    (
                        3,
                        "Python",
                    ),
                ),
            ),
            
            [
                "DELETE FROM i_love_ponies WHERE special_thing = 'Django';",
                ["DELETE FROM i_love_ponies WHERE special_thing = 'Ponies';", None],
                (
                    "DELETE FROM i_love_ponies WHERE id = %s OR special_thing = %s;",
                    [3, "Python"],
                ),
            ],
        )

        
        self.assertTableNotExists("i_love_ponies")
        new_state = project_state.clone()
        
        with connection.schema_editor() as editor:
            operation.database_forwards("test_runsql", editor, project_state, new_state)

        
        with connection.schema_editor() as editor:
            param_operation.database_forwards(
                "test_runsql", editor, project_state, new_state
            )
        
        with connection.cursor() as cursor:
            cursor.execute("SELECT COUNT(*) FROM i_love_ponies")
            self.assertEqual(cursor.fetchall()[0][0], 3)

        with connection.schema_editor() as editor:
            param_operation.database_backwards(
                "test_runsql", editor, new_state, project_state
            )
        with connection.cursor() as cursor:
            cursor.execute("SELECT COUNT(*) FROM i_love_ponies")
            self.assertEqual(cursor.fetchall()[0][0], 0)

        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_runsql", editor, new_state, project_state
            )
        self.assertTableNotExists("i_love_ponies")

    def test_run_sql_params_invalid(self):
        
        project_state = self.set_up_test_model("test_runsql")
        new_state = project_state.clone()
        operation = migrations.RunSQL(
            
            [["INSERT INTO foo (bar) VALUES ('buz');"]],
            
            (("DELETE FROM foo WHERE bar = 'buz';", "invalid", "parameter count"),),
        )

        with connection.schema_editor() as editor:
            with self.assertRaisesMessage(ValueError, "Expected a 2-tuple but got 1"):
                operation.database_forwards(
                    "test_runsql", editor, project_state, new_state
                )

        with connection.schema_editor() as editor:
            with self.assertRaisesMessage(ValueError, "Expected a 2-tuple but got 3"):
                operation.database_backwards(
                    "test_runsql", editor, new_state, project_state
                )

    def test_run_sql_noop(self):
        
        operation = migrations.RunSQL(migrations.RunSQL.noop, migrations.RunSQL.noop)
        with connection.schema_editor() as editor:
            operation.database_forwards("test_runsql", editor, None, None)
            operation.database_backwards("test_runsql", editor, None, None)

    def test_run_sql_add_missing_semicolon_on_collect_sql(self):
        project_state = self.set_up_test_model("test_runsql")
        new_state = project_state.clone()
        tests = [
            "INSERT INTO test_runsql_pony (pink, weight) VALUES (1, 1);\n",
            "INSERT INTO test_runsql_pony (pink, weight) VALUES (1, 1)\n",
        ]
        for sql in tests:
            with self.subTest(sql=sql):
                operation = migrations.RunSQL(sql, migrations.RunPython.noop)
                with connection.schema_editor(collect_sql=True) as editor:
                    operation.database_forwards(
                        "test_runsql", editor, project_state, new_state
                    )
                    collected_sql = "\n".join(editor.collected_sql)
                    self.assertEqual(collected_sql.count(";"), 1)

    def test_run_python(self):
        

        project_state = self.set_up_test_model("test_runpython", mti_model=True)

        
        def inner_method(models, schema_editor):
            Pony = models.get_model("test_runpython", "Pony")
            Pony.objects.create(pink=1, weight=3.55)
            Pony.objects.create(weight=5)

        def inner_method_reverse(models, schema_editor):
            Pony = models.get_model("test_runpython", "Pony")
            Pony.objects.filter(pink=1, weight=3.55).delete()
            Pony.objects.filter(weight=5).delete()

        operation = migrations.RunPython(
            inner_method, reverse_code=inner_method_reverse
        )
        self.assertEqual(operation.describe(), "Raw Python operation")
        
        new_state = project_state.clone()
        operation.state_forwards("test_runpython", new_state)
        self.assertEqual(new_state, project_state)
        
        self.assertEqual(
            project_state.apps.get_model("test_runpython", "Pony").objects.count(), 0
        )
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_runpython", editor, project_state, new_state
            )
        self.assertEqual(
            project_state.apps.get_model("test_runpython", "Pony").objects.count(), 2
        )
        
        self.assertTrue(operation.reversible)
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_runpython", editor, project_state, new_state
            )
        self.assertEqual(
            project_state.apps.get_model("test_runpython", "Pony").objects.count(), 0
        )
        
        with self.assertRaisesMessage(
            ValueError, "RunPython must be supplied with a callable"
        ):
            migrations.RunPython("print 'ahahaha'")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RunPython")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["code", "reverse_code"])

        
        
        no_reverse_operation = migrations.RunPython(inner_method)
        self.assertFalse(no_reverse_operation.reversible)
        with connection.schema_editor() as editor:
            no_reverse_operation.database_forwards(
                "test_runpython", editor, project_state, new_state
            )
            with self.assertRaises(NotImplementedError):
                no_reverse_operation.database_backwards(
                    "test_runpython", editor, new_state, project_state
                )
        self.assertEqual(
            project_state.apps.get_model("test_runpython", "Pony").objects.count(), 2
        )

        def create_ponies(models, schema_editor):
            Pony = models.get_model("test_runpython", "Pony")
            pony1 = Pony.objects.create(pink=1, weight=3.55)
            self.assertIsNot(pony1.pk, None)
            pony2 = Pony.objects.create(weight=5)
            self.assertIsNot(pony2.pk, None)
            self.assertNotEqual(pony1.pk, pony2.pk)

        operation = migrations.RunPython(create_ponies)
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_runpython", editor, project_state, new_state
            )
        self.assertEqual(
            project_state.apps.get_model("test_runpython", "Pony").objects.count(), 4
        )
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "RunPython")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["code"])

        def create_shetlandponies(models, schema_editor):
            ShetlandPony = models.get_model("test_runpython", "ShetlandPony")
            pony1 = ShetlandPony.objects.create(weight=4.0)
            self.assertIsNot(pony1.pk, None)
            pony2 = ShetlandPony.objects.create(weight=5.0)
            self.assertIsNot(pony2.pk, None)
            self.assertNotEqual(pony1.pk, pony2.pk)

        operation = migrations.RunPython(create_shetlandponies)
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_runpython", editor, project_state, new_state
            )
        self.assertEqual(
            project_state.apps.get_model("test_runpython", "Pony").objects.count(), 6
        )
        self.assertEqual(
            project_state.apps.get_model(
                "test_runpython", "ShetlandPony"
            ).objects.count(),
            2,
        )
        
        self.assertIs(False, operation.reduce(operation, []))
        elidable_operation = migrations.RunPython(inner_method, elidable=True)
        self.assertEqual(elidable_operation.reduce(operation, []), [operation])

    def test_run_python_atomic(self):
        
        project_state = self.set_up_test_model("test_runpythonatomic", mti_model=True)

        def inner_method(models, schema_editor):
            Pony = models.get_model("test_runpythonatomic", "Pony")
            Pony.objects.create(pink=1, weight=3.55)
            raise ValueError("Adrian hates ponies.")

        
        atomic_migration = Migration("test", "test_runpythonatomic")
        atomic_migration.operations = [
            migrations.RunPython(inner_method, reverse_code=inner_method)
        ]
        non_atomic_migration = Migration("test", "test_runpythonatomic")
        non_atomic_migration.operations = [
            migrations.RunPython(inner_method, reverse_code=inner_method, atomic=False)
        ]
        
        if connection.features.can_rollback_ddl:
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    atomic_migration.apply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    non_atomic_migration.apply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
        
        else:
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    atomic_migration.apply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    non_atomic_migration.apply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                1,
            )
        
        project_state.apps.get_model(
            "test_runpythonatomic", "Pony"
        ).objects.all().delete()
        
        if connection.features.can_rollback_ddl:
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    atomic_migration.unapply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    non_atomic_migration.unapply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
        
        else:
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    atomic_migration.unapply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                0,
            )
            with self.assertRaises(ValueError):
                with connection.schema_editor() as editor:
                    non_atomic_migration.unapply(project_state, editor)
            self.assertEqual(
                project_state.apps.get_model(
                    "test_runpythonatomic", "Pony"
                ).objects.count(),
                1,
            )
        
        definition = non_atomic_migration.operations[0].deconstruct()
        self.assertEqual(definition[0], "RunPython")
        self.assertEqual(definition[1], [])
        self.assertEqual(sorted(definition[2]), ["atomic", "code", "reverse_code"])

    def test_run_python_related_assignment(self):
        

        def inner_method(models, schema_editor):
            Author = models.get_model("test_authors", "Author")
            Book = models.get_model("test_books", "Book")
            author = Author.objects.create(name="Hemingway")
            Book.objects.create(title="Old Man and The Sea", author=author)

        create_author = migrations.CreateModel(
            "Author",
            [
                ("id", models.AutoField(primary_key=True)),
                ("name", models.CharField(max_length=100)),
            ],
            options={},
        )
        create_book = migrations.CreateModel(
            "Book",
            [
                ("id", models.AutoField(primary_key=True)),
                ("title", models.CharField(max_length=100)),
                ("author", models.ForeignKey("test_authors.Author", models.CASCADE)),
            ],
            options={},
        )
        add_hometown = migrations.AddField(
            "Author",
            "hometown",
            models.CharField(max_length=100),
        )
        create_old_man = migrations.RunPython(inner_method, inner_method)

        project_state = ProjectState()
        new_state = project_state.clone()
        with connection.schema_editor() as editor:
            create_author.state_forwards("test_authors", new_state)
            create_author.database_forwards(
                "test_authors", editor, project_state, new_state
            )
        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            create_book.state_forwards("test_books", new_state)
            create_book.database_forwards(
                "test_books", editor, project_state, new_state
            )
        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            add_hometown.state_forwards("test_authors", new_state)
            add_hometown.database_forwards(
                "test_authors", editor, project_state, new_state
            )
        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            create_old_man.state_forwards("test_books", new_state)
            create_old_man.database_forwards(
                "test_books", editor, project_state, new_state
            )

    def test_model_with_bigautofield(self):
        

        def create_data(models, schema_editor):
            Author = models.get_model("test_author", "Author")
            Book = models.get_model("test_book", "Book")
            author1 = Author.objects.create(name="Hemingway")
            Book.objects.create(title="Old Man and The Sea", author=author1)
            Book.objects.create(id=2**33, title="A farewell to arms", author=author1)

            author2 = Author.objects.create(id=2**33, name="Remarque")
            Book.objects.create(title="All quiet on the western front", author=author2)
            Book.objects.create(title="Arc de Triomphe", author=author2)

        create_author = migrations.CreateModel(
            "Author",
            [
                ("id", models.BigAutoField(primary_key=True)),
                ("name", models.CharField(max_length=100)),
            ],
            options={},
        )
        create_book = migrations.CreateModel(
            "Book",
            [
                ("id", models.BigAutoField(primary_key=True)),
                ("title", models.CharField(max_length=100)),
                (
                    "author",
                    models.ForeignKey(
                        to="test_author.Author", on_delete=models.CASCADE
                    ),
                ),
            ],
            options={},
        )
        fill_data = migrations.RunPython(create_data)

        project_state = ProjectState()
        new_state = project_state.clone()
        with connection.schema_editor() as editor:
            create_author.state_forwards("test_author", new_state)
            create_author.database_forwards(
                "test_author", editor, project_state, new_state
            )

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            create_book.state_forwards("test_book", new_state)
            create_book.database_forwards("test_book", editor, project_state, new_state)

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            fill_data.state_forwards("fill_data", new_state)
            fill_data.database_forwards("fill_data", editor, project_state, new_state)

    def _test_autofield_foreignfield_growth(
        self, source_field, target_field, target_value
    ):
        

        def create_initial_data(models, schema_editor):
            Article = models.get_model("test_article", "Article")
            Blog = models.get_model("test_blog", "Blog")
            blog = Blog.objects.create(name="web development done right")
            Article.objects.create(name="Frameworks", blog=blog)
            Article.objects.create(name="Programming Languages", blog=blog)

        def create_big_data(models, schema_editor):
            Article = models.get_model("test_article", "Article")
            Blog = models.get_model("test_blog", "Blog")
            blog2 = Blog.objects.create(name="Frameworks", id=target_value)
            Article.objects.create(name="Django", blog=blog2)
            Article.objects.create(id=target_value, name="Django2", blog=blog2)

        create_blog = migrations.CreateModel(
            "Blog",
            [
                ("id", source_field(primary_key=True)),
                ("name", models.CharField(max_length=100)),
            ],
            options={},
        )
        create_article = migrations.CreateModel(
            "Article",
            [
                ("id", source_field(primary_key=True)),
                (
                    "blog",
                    models.ForeignKey(to="test_blog.Blog", on_delete=models.CASCADE),
                ),
                ("name", models.CharField(max_length=100)),
                ("data", models.TextField(default="")),
            ],
            options={},
        )
        fill_initial_data = migrations.RunPython(
            create_initial_data, create_initial_data
        )
        fill_big_data = migrations.RunPython(create_big_data, create_big_data)

        grow_article_id = migrations.AlterField(
            "Article", "id", target_field(primary_key=True)
        )
        grow_blog_id = migrations.AlterField(
            "Blog", "id", target_field(primary_key=True)
        )

        project_state = ProjectState()
        new_state = project_state.clone()
        with connection.schema_editor() as editor:
            create_blog.state_forwards("test_blog", new_state)
            create_blog.database_forwards("test_blog", editor, project_state, new_state)

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            create_article.state_forwards("test_article", new_state)
            create_article.database_forwards(
                "test_article", editor, project_state, new_state
            )

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            fill_initial_data.state_forwards("fill_initial_data", new_state)
            fill_initial_data.database_forwards(
                "fill_initial_data", editor, project_state, new_state
            )

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            grow_article_id.state_forwards("test_article", new_state)
            grow_article_id.database_forwards(
                "test_article", editor, project_state, new_state
            )

        state = new_state.clone()
        article = state.apps.get_model("test_article.Article")
        self.assertIsInstance(article._meta.pk, target_field)

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            grow_blog_id.state_forwards("test_blog", new_state)
            grow_blog_id.database_forwards(
                "test_blog", editor, project_state, new_state
            )

        state = new_state.clone()
        blog = state.apps.get_model("test_blog.Blog")
        self.assertIsInstance(blog._meta.pk, target_field)

        project_state = new_state
        new_state = new_state.clone()
        with connection.schema_editor() as editor:
            fill_big_data.state_forwards("fill_big_data", new_state)
            fill_big_data.database_forwards(
                "fill_big_data", editor, project_state, new_state
            )

    def test_autofield__bigautofield_foreignfield_growth(self):
        
        self._test_autofield_foreignfield_growth(
            models.AutoField,
            models.BigAutoField,
            2**33,
        )

    def test_smallfield_autofield_foreignfield_growth(self):
        
        self._test_autofield_foreignfield_growth(
            models.SmallAutoField,
            models.AutoField,
            2**22,
        )

    def test_smallfield_bigautofield_foreignfield_growth(self):
        
        self._test_autofield_foreignfield_growth(
            models.SmallAutoField,
            models.BigAutoField,
            2**33,
        )

    def test_run_python_noop(self):
        
        project_state = ProjectState()
        new_state = project_state.clone()
        operation = migrations.RunPython(
            migrations.RunPython.noop, migrations.RunPython.noop
        )
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_runpython", editor, project_state, new_state
            )
            operation.database_backwards(
                "test_runpython", editor, new_state, project_state
            )

    def test_separate_database_and_state(self):
        
        project_state = self.set_up_test_model("test_separatedatabaseandstate")
        
        database_operation = migrations.RunSQL(
            "CREATE TABLE i_love_ponies (id int, special_thing int);",
            "DROP TABLE i_love_ponies;",
        )
        state_operation = migrations.CreateModel(
            "SomethingElse", [("id", models.AutoField(primary_key=True))]
        )
        operation = migrations.SeparateDatabaseAndState(
            state_operations=[state_operation], database_operations=[database_operation]
        )
        self.assertEqual(
            operation.describe(), "Custom state/database change combination"
        )
        
        new_state = project_state.clone()
        operation.state_forwards("test_separatedatabaseandstate", new_state)
        self.assertEqual(
            len(
                new_state.models[
                    "test_separatedatabaseandstate", "somethingelse"
                ].fields
            ),
            1,
        )
        
        self.assertTableNotExists("i_love_ponies")
        
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_separatedatabaseandstate", editor, project_state, new_state
            )
        self.assertTableExists("i_love_ponies")
        
        self.assertTrue(operation.reversible)
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_separatedatabaseandstate", editor, new_state, project_state
            )
        self.assertTableNotExists("i_love_ponies")
        
        definition = operation.deconstruct()
        self.assertEqual(definition[0], "SeparateDatabaseAndState")
        self.assertEqual(definition[1], [])
        self.assertEqual(
            sorted(definition[2]), ["database_operations", "state_operations"]
        )

    def test_separate_database_and_state2(self):
        
        app_label = "test_separatedatabaseandstate2"
        project_state = self.set_up_test_model(app_label)
        
        database_operations = [
            migrations.CreateModel(
                "ILovePonies",
                [("id", models.AutoField(primary_key=True))],
                options={"db_table": "iloveponies"},
            ),
            migrations.CreateModel(
                "ILoveMorePonies",
                
                
                
                [("id", models.IntegerField(primary_key=True))],
                options={"db_table": "ilovemoreponies"},
            ),
            migrations.DeleteModel("ILoveMorePonies"),
            migrations.CreateModel(
                "ILoveEvenMorePonies",
                [("id", models.AutoField(primary_key=True))],
                options={"db_table": "iloveevenmoreponies"},
            ),
        ]
        state_operations = [
            migrations.CreateModel(
                "SomethingElse",
                [("id", models.AutoField(primary_key=True))],
                options={"db_table": "somethingelse"},
            ),
            migrations.DeleteModel("SomethingElse"),
            migrations.CreateModel(
                "SomethingCompletelyDifferent",
                [("id", models.AutoField(primary_key=True))],
                options={"db_table": "somethingcompletelydifferent"},
            ),
        ]
        operation = migrations.SeparateDatabaseAndState(
            state_operations=state_operations,
            database_operations=database_operations,
        )
        
        new_state = project_state.clone()
        operation.state_forwards(app_label, new_state)

        def assertModelsAndTables(after_db):
            
            self.assertNotIn((app_label, "somethingelse"), new_state.models)
            self.assertEqual(
                len(new_state.models[app_label, "somethingcompletelydifferent"].fields),
                1,
            )
            self.assertNotIn((app_label, "iloveponiesonies"), new_state.models)
            self.assertNotIn((app_label, "ilovemoreponies"), new_state.models)
            self.assertNotIn((app_label, "iloveevenmoreponies"), new_state.models)
            self.assertTableNotExists("somethingelse")
            self.assertTableNotExists("somethingcompletelydifferent")
            self.assertTableNotExists("ilovemoreponies")
            if after_db:
                self.assertTableExists("iloveponies")
                self.assertTableExists("iloveevenmoreponies")
            else:
                self.assertTableNotExists("iloveponies")
                self.assertTableNotExists("iloveevenmoreponies")

        assertModelsAndTables(after_db=False)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        assertModelsAndTables(after_db=True)
        
        self.assertTrue(operation.reversible)
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        assertModelsAndTables(after_db=False)

    def _test_invalid_generated_field_changes(self, db_persist):
        regular = models.IntegerField(default=1)
        generated_1 = models.GeneratedField(
            expression=F("pink") + F("pink"),
            output_field=models.IntegerField(),
            db_persist=db_persist,
        )
        generated_2 = models.GeneratedField(
            expression=F("pink") + F("pink") + F("pink"),
            output_field=models.IntegerField(),
            db_persist=db_persist,
        )
        tests = [
            ("test_igfc_1", regular, generated_1),
            ("test_igfc_2", generated_1, regular),
            ("test_igfc_3", generated_1, generated_2),
        ]
        for app_label, add_field, alter_field in tests:
            project_state = self.set_up_test_model(app_label)
            operations = [
                migrations.AddField("Pony", "modified_pink", add_field),
                migrations.AlterField("Pony", "modified_pink", alter_field),
            ]
            msg = (
                "Modifying GeneratedFields is not supported - the field "
                f"{app_label}.Pony.modified_pink must be removed and re-added with the "
                "new definition."
            )
            with self.assertRaisesMessage(ValueError, msg):
                self.apply_operations(app_label, project_state, operations)

    @skipUnlessDBFeature("supports_stored_generated_columns")
    def test_invalid_generated_field_changes_stored(self):
        self._test_invalid_generated_field_changes(db_persist=True)

    @skipUnlessDBFeature("supports_virtual_generated_columns")
    def test_invalid_generated_field_changes_virtual(self):
        self._test_invalid_generated_field_changes(db_persist=False)

    @skipUnlessDBFeature(
        "supports_stored_generated_columns",
        "supports_virtual_generated_columns",
    )
    def test_invalid_generated_field_persistency_change(self):
        app_label = "test_igfpc"
        project_state = self.set_up_test_model(app_label)
        operations = [
            migrations.AddField(
                "Pony",
                "modified_pink",
                models.GeneratedField(
                    expression=F("pink"),
                    output_field=models.IntegerField(),
                    db_persist=True,
                ),
            ),
            migrations.AlterField(
                "Pony",
                "modified_pink",
                models.GeneratedField(
                    expression=F("pink"),
                    output_field=models.IntegerField(),
                    db_persist=False,
                ),
            ),
        ]
        msg = (
            "Modifying GeneratedFields is not supported - the field "
            f"{app_label}.Pony.modified_pink must be removed and re-added with the "
            "new definition."
        )
        with self.assertRaisesMessage(ValueError, msg):
            self.apply_operations(app_label, project_state, operations)

    def _test_add_generated_field(self, db_persist):
        app_label = "test_agf"
        operation = migrations.AddField(
            "Pony",
            "modified_pink",
            models.GeneratedField(
                expression=F("pink") + F("pink"),
                output_field=models.IntegerField(),
                db_persist=db_persist,
            ),
        )
        project_state, new_state = self.make_test_state(app_label, operation)
        self.assertEqual(len(new_state.models[app_label, "pony"].fields), 6)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnExists(f"{app_label}_pony", "modified_pink")
        Pony = new_state.apps.get_model(app_label, "Pony")
        obj = Pony.objects.create(pink=5, weight=3.23)
        self.assertEqual(obj.modified_pink, 10)
        
        with connection.schema_editor() as editor:
            operation.database_backwards(app_label, editor, new_state, project_state)
        self.assertColumnNotExists(f"{app_label}_pony", "modified_pink")

    @skipUnlessDBFeature("supports_stored_generated_columns")
    def test_add_generated_field_stored(self):
        self._test_add_generated_field(db_persist=True)

    @skipUnlessDBFeature("supports_virtual_generated_columns")
    def test_add_generated_field_virtual(self):
        self._test_add_generated_field(db_persist=False)

    def _test_remove_generated_field(self, db_persist):
        app_label = "test_rgf"
        operation = migrations.AddField(
            "Pony",
            "modified_pink",
            models.GeneratedField(
                expression=F("pink") + F("pink"),
                output_field=models.IntegerField(),
                db_persist=db_persist,
            ),
        )
        project_state, new_state = self.make_test_state(app_label, operation)
        self.assertEqual(len(new_state.models[app_label, "pony"].fields), 6)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        project_state = new_state
        new_state = project_state.clone()
        operation = migrations.RemoveField("Pony", "modified_pink")
        operation.state_forwards(app_label, new_state)
        
        with connection.schema_editor() as editor:
            operation.database_forwards(app_label, editor, project_state, new_state)
        self.assertColumnNotExists(f"{app_label}_pony", "modified_pink")

    @skipUnlessDBFeature("supports_stored_generated_columns")
    def test_remove_generated_field_stored(self):
        self._test_remove_generated_field(db_persist=True)

    @skipUnlessDBFeature("supports_virtual_generated_columns")
    def test_remove_generated_field_virtual(self):
        self._test_remove_generated_field(db_persist=False)

    @skipUnlessDBFeature("supports_stored_generated_columns")
    def test_add_field_after_generated_field(self):
        app_label = "test_adfagf"
        project_state = self.set_up_test_model(app_label)
        operation_1 = migrations.AddField(
            "Pony",
            "generated",
            models.GeneratedField(
                expression=Value(1),
                output_field=models.IntegerField(),
                db_persist=True,
            ),
        )
        operation_2 = migrations.AddField(
            "Pony",
            "static",
            models.IntegerField(default=2),
        )
        new_state = project_state.clone()
        operation_1.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation_1.database_forwards(app_label, editor, project_state, new_state)
        project_state, new_state = new_state, new_state.clone()
        pony_old = new_state.apps.get_model(app_label, "Pony").objects.create(weight=20)
        self.assertEqual(pony_old.generated, 1)
        operation_2.state_forwards(app_label, new_state)
        with connection.schema_editor() as editor:
            operation_2.database_forwards(app_label, editor, project_state, new_state)
        Pony = new_state.apps.get_model(app_label, "Pony")
        pony_old = Pony.objects.get(pk=pony_old.pk)
        self.assertEqual(pony_old.generated, 1)
        self.assertEqual(pony_old.static, 2)
        pony_new = Pony.objects.create(weight=20)
        self.assertEqual(pony_new.generated, 1)
        self.assertEqual(pony_new.static, 2)


class SwappableOperationTests(OperationTestBase):
    

    available_apps = ["migrations"]

    @override_settings(TEST_SWAP_MODEL="migrations.SomeFakeModel")
    def test_create_ignore_swapped(self):
        
        operation = migrations.CreateModel(
            "Pony",
            [
                ("id", models.AutoField(primary_key=True)),
                ("pink", models.IntegerField(default=1)),
            ],
            options={
                "swappable": "TEST_SWAP_MODEL",
            },
        )
        
        project_state = ProjectState()
        new_state = project_state.clone()
        operation.state_forwards("test_crigsw", new_state)
        self.assertEqual(new_state.models["test_crigsw", "pony"].name, "Pony")
        self.assertEqual(len(new_state.models["test_crigsw", "pony"].fields), 2)
        
        self.assertTableNotExists("test_crigsw_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_crigsw", editor, project_state, new_state)
        self.assertTableNotExists("test_crigsw_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_crigsw", editor, new_state, project_state
            )
        self.assertTableNotExists("test_crigsw_pony")

    @override_settings(TEST_SWAP_MODEL="migrations.SomeFakeModel")
    def test_delete_ignore_swapped(self):
        
        operation = migrations.DeleteModel("Pony")
        project_state, new_state = self.make_test_state("test_dligsw", operation)
        
        self.assertTableNotExists("test_dligsw_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards("test_dligsw", editor, project_state, new_state)
        self.assertTableNotExists("test_dligsw_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_dligsw", editor, new_state, project_state
            )
        self.assertTableNotExists("test_dligsw_pony")

    @override_settings(TEST_SWAP_MODEL="migrations.SomeFakeModel")
    def test_add_field_ignore_swapped(self):
        
        
        operation = migrations.AddField(
            "Pony",
            "height",
            models.FloatField(null=True, default=5),
        )
        project_state, new_state = self.make_test_state("test_adfligsw", operation)
        
        self.assertTableNotExists("test_adfligsw_pony")
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_adfligsw", editor, project_state, new_state
            )
        self.assertTableNotExists("test_adfligsw_pony")
        
        with connection.schema_editor() as editor:
            operation.database_backwards(
                "test_adfligsw", editor, new_state, project_state
            )
        self.assertTableNotExists("test_adfligsw_pony")

    @override_settings(TEST_SWAP_MODEL="migrations.SomeFakeModel")
    def test_indexes_ignore_swapped(self):
        
        operation = migrations.AddIndex(
            "Pony", models.Index(fields=["pink"], name="my_name_idx")
        )
        project_state, new_state = self.make_test_state("test_adinigsw", operation)
        with connection.schema_editor() as editor:
            
            operation.database_forwards(
                "test_adinigsw", editor, project_state, new_state
            )
            operation.database_backwards(
                "test_adinigsw", editor, new_state, project_state
            )

        operation = migrations.RemoveIndex(
            "Pony", models.Index(fields=["pink"], name="my_name_idx")
        )
        project_state, new_state = self.make_test_state("test_rminigsw", operation)
        with connection.schema_editor() as editor:
            operation.database_forwards(
                "test_rminigsw", editor, project_state, new_state
            )
            operation.database_backwards(
                "test_rminigsw", editor, new_state, project_state
            )


class TestCreateModel(SimpleTestCase):
    def test_references_model_mixin(self):
        migrations.CreateModel(
            "name",
            fields=[],
            bases=(Mixin, models.Model),
        ).references_model("other_model", "migrations")


class FieldOperationTests(SimpleTestCase):
    def test_references_model(self):
        operation = FieldOperation(
            "MoDel", "field", models.ForeignKey("Other", models.CASCADE)
        )
        
        self.assertIs(operation.references_model("mOdEl", "migrations"), True)
        
        self.assertIs(operation.references_model("oTher", "migrations"), True)
        
        self.assertIs(operation.references_model("Whatever", "migrations"), False)

    def test_references_field_by_name(self):
        operation = FieldOperation("MoDel", "field", models.BooleanField(default=False))
        self.assertIs(operation.references_field("model", "field", "migrations"), True)

    def test_references_field_by_remote_field_model(self):
        operation = FieldOperation(
            "Model", "field", models.ForeignKey("Other", models.CASCADE)
        )
        self.assertIs(
            operation.references_field("Other", "whatever", "migrations"), True
        )
        self.assertIs(
            operation.references_field("Missing", "whatever", "migrations"), False
        )

    def test_references_field_by_from_fields(self):
        operation = FieldOperation(
            "Model",
            "field",
            models.fields.related.ForeignObject(
                "Other", models.CASCADE, ["from"], ["to"]
            ),
        )
        self.assertIs(operation.references_field("Model", "from", "migrations"), True)
        self.assertIs(operation.references_field("Model", "to", "migrations"), False)
        self.assertIs(operation.references_field("Other", "from", "migrations"), False)
        self.assertIs(operation.references_field("Model", "to", "migrations"), False)

    def test_references_field_by_to_fields(self):
        operation = FieldOperation(
            "Model",
            "field",
            models.ForeignKey("Other", models.CASCADE, to_field="field"),
        )
        self.assertIs(operation.references_field("Other", "field", "migrations"), True)
        self.assertIs(
            operation.references_field("Other", "whatever", "migrations"), False
        )
        self.assertIs(
            operation.references_field("Missing", "whatever", "migrations"), False
        )

    def test_references_field_by_through(self):
        operation = FieldOperation(
            "Model", "field", models.ManyToManyField("Other", through="Through")
        )
        self.assertIs(
            operation.references_field("Other", "whatever", "migrations"), True
        )
        self.assertIs(
            operation.references_field("Through", "whatever", "migrations"), True
        )
        self.assertIs(
            operation.references_field("Missing", "whatever", "migrations"), False
        )

    def test_reference_field_by_through_fields(self):
        operation = FieldOperation(
            "Model",
            "field",
            models.ManyToManyField(
                "Other", through="Through", through_fields=("first", "second")
            ),
        )
        self.assertIs(
            operation.references_field("Other", "whatever", "migrations"), True
        )
        self.assertIs(
            operation.references_field("Through", "whatever", "migrations"), False
        )
        self.assertIs(
            operation.references_field("Through", "first", "migrations"), True
        )
        self.assertIs(
            operation.references_field("Through", "second", "migrations"), True
        )