[{"data":1,"prerenderedAt":1218},["ShallowReactive",2],{"\u002Ffix-issues\u002Fflask-migrations-not-applied-fix-guide":3},{"id":4,"title":5,"body":6,"description":1208,"extension":1209,"meta":1210,"navigation":60,"path":1214,"seo":1215,"stem":1216,"__hash__":1217},"content\u002Ffix-issues\u002Fflask-migrations-not-applied-fix-guide.md","Flask Migrations Not Applied (Fix Guide)",{"type":7,"value":8,"toc":1197},"minimark",[9,13,17,22,25,249,252,256,267,271,760,764,831,835,838,999,1002,1036,1043,1047,1095,1102,1106,1126,1130,1145,1156,1164,1172,1186,1190,1193],[10,11,5],"h1",{"id":12},"flask-migrations-not-applied-fix-guide",[14,15,16],"p",{},"If you're seeing missing tables, column errors, or deployment failures because Flask database migrations were not applied, this guide shows you how to diagnose and fix it step-by-step. The goal is to confirm the migration state, apply the correct revision, and verify the production database matches the running code.",[18,19,21],"h2",{"id":20},"quick-fix-quick-setup","Quick Fix \u002F Quick Setup",[14,23,24],{},"Run migration commands on the server using the same virtualenv, Flask app entrypoint, and database configuration used by the production service.",[26,27,32],"pre",{"className":28,"code":29,"language":30,"meta":31,"style":31},"language-bash shiki shiki-themes github-light github-dark","# Activate the correct environment\nsource \u002Fpath\u002Fto\u002Fvenv\u002Fbin\u002Factivate\n\n# Load production environment variables if needed\nexport FLASK_APP=wsgi.py\nexport FLASK_ENV=production\nexport DATABASE_URL='postgresql:\u002F\u002Fuser:pass@host\u002Fdbname'\n\n# Check current revision\nflask db current\n\n# See unapplied migrations\nflask db heads\nflask db history\n\n# Apply pending migrations\nflask db upgrade\n\n# Verify schema state\nflask db current\n\n# If using systemd, restart the app after success\nsudo systemctl restart gunicorn\nsudo systemctl status gunicorn --no-pager\n","bash","",[33,34,35,44,55,62,68,85,98,111,116,122,135,140,146,156,166,171,177,187,192,198,207,212,218,233],"code",{"__ignoreMap":31},[36,37,40],"span",{"class":38,"line":39},"line",1,[36,41,43],{"class":42},"sJ8bj","# Activate the correct environment\n",[36,45,47,51],{"class":38,"line":46},2,[36,48,50],{"class":49},"sj4cs","source",[36,52,54],{"class":53},"sZZnC"," \u002Fpath\u002Fto\u002Fvenv\u002Fbin\u002Factivate\n",[36,56,58],{"class":38,"line":57},3,[36,59,61],{"emptyLinePlaceholder":60},true,"\n",[36,63,65],{"class":38,"line":64},4,[36,66,67],{"class":42},"# Load production environment variables if needed\n",[36,69,71,75,79,82],{"class":38,"line":70},5,[36,72,74],{"class":73},"szBVR","export",[36,76,78],{"class":77},"sVt8B"," FLASK_APP",[36,80,81],{"class":73},"=",[36,83,84],{"class":77},"wsgi.py\n",[36,86,88,90,93,95],{"class":38,"line":87},6,[36,89,74],{"class":73},[36,91,92],{"class":77}," FLASK_ENV",[36,94,81],{"class":73},[36,96,97],{"class":77},"production\n",[36,99,101,103,106,108],{"class":38,"line":100},7,[36,102,74],{"class":73},[36,104,105],{"class":77}," DATABASE_URL",[36,107,81],{"class":73},[36,109,110],{"class":53},"'postgresql:\u002F\u002Fuser:pass@host\u002Fdbname'\n",[36,112,114],{"class":38,"line":113},8,[36,115,61],{"emptyLinePlaceholder":60},[36,117,119],{"class":38,"line":118},9,[36,120,121],{"class":42},"# Check current revision\n",[36,123,125,129,132],{"class":38,"line":124},10,[36,126,128],{"class":127},"sScJk","flask",[36,130,131],{"class":53}," db",[36,133,134],{"class":53}," current\n",[36,136,138],{"class":38,"line":137},11,[36,139,61],{"emptyLinePlaceholder":60},[36,141,143],{"class":38,"line":142},12,[36,144,145],{"class":42},"# See unapplied migrations\n",[36,147,149,151,153],{"class":38,"line":148},13,[36,150,128],{"class":127},[36,152,131],{"class":53},[36,154,155],{"class":53}," heads\n",[36,157,159,161,163],{"class":38,"line":158},14,[36,160,128],{"class":127},[36,162,131],{"class":53},[36,164,165],{"class":53}," history\n",[36,167,169],{"class":38,"line":168},15,[36,170,61],{"emptyLinePlaceholder":60},[36,172,174],{"class":38,"line":173},16,[36,175,176],{"class":42},"# Apply pending migrations\n",[36,178,180,182,184],{"class":38,"line":179},17,[36,181,128],{"class":127},[36,183,131],{"class":53},[36,185,186],{"class":53}," upgrade\n",[36,188,190],{"class":38,"line":189},18,[36,191,61],{"emptyLinePlaceholder":60},[36,193,195],{"class":38,"line":194},19,[36,196,197],{"class":42},"# Verify schema state\n",[36,199,201,203,205],{"class":38,"line":200},20,[36,202,128],{"class":127},[36,204,131],{"class":53},[36,206,134],{"class":53},[36,208,210],{"class":38,"line":209},21,[36,211,61],{"emptyLinePlaceholder":60},[36,213,215],{"class":38,"line":214},22,[36,216,217],{"class":42},"# If using systemd, restart the app after success\n",[36,219,221,224,227,230],{"class":38,"line":220},23,[36,222,223],{"class":127},"sudo",[36,225,226],{"class":53}," systemctl",[36,228,229],{"class":53}," restart",[36,231,232],{"class":53}," gunicorn\n",[36,234,236,238,240,243,246],{"class":38,"line":235},24,[36,237,223],{"class":127},[36,239,226],{"class":53},[36,241,242],{"class":53}," status",[36,244,245],{"class":53}," gunicorn",[36,247,248],{"class":49}," --no-pager\n",[14,250,251],{},"Most migration issues happen because commands are run in the wrong environment or against the wrong database.",[18,253,255],{"id":254},"whats-happening","What’s Happening",[14,257,258,259,262,263,266],{},"Flask-Migrate and Alembic track schema revisions in the database with an ",[33,260,261],{},"alembic_version"," table. If new migration files exist in your codebase but ",[33,264,265],{},"flask db upgrade"," was skipped, failed, or targeted a different database, your app runs against an outdated schema. This usually appears as missing table errors, undefined column errors, duplicate column errors, or app startup failures after deployment.",[18,268,270],{"id":269},"step-by-step-guide","Step-by-Step Guide",[272,273,274,346,380,422,479,527,565,630,665,690],"ol",{},[275,276,277,281,284,285,305,307,308,324,326,327],"li",{},[278,279,280],"strong",{},"Confirm the production app is using the expected database",[282,283],"br",{},"Check the environment variables used by systemd, Docker, or your shell.",[26,286,288],{"className":28,"code":287,"language":30,"meta":31,"style":31},"echo $FLASK_APP\necho $DATABASE_URL\n",[33,289,290,298],{"__ignoreMap":31},[36,291,292,295],{"class":38,"line":39},[36,293,294],{"class":49},"echo",[36,296,297],{"class":77}," $FLASK_APP\n",[36,299,300,302],{"class":38,"line":46},[36,301,294],{"class":49},[36,303,304],{"class":77}," $DATABASE_URL\n",[282,306],{},"If you use systemd, inspect the service definition:",[26,309,311],{"className":28,"code":310,"language":30,"meta":31,"style":31},"sudo systemctl cat gunicorn\n",[33,312,313],{"__ignoreMap":31},[36,314,315,317,319,322],{"class":38,"line":39},[36,316,223],{"class":127},[36,318,226],{"class":53},[36,320,321],{"class":53}," cat",[36,323,232],{"class":53},[282,325],{},"Look for:",[328,329,330,335,340,343],"ul",{},[275,331,332],{},[33,333,334],{},"Environment=",[275,336,337],{},[33,338,339],{},"EnvironmentFile=",[275,341,342],{},"the app working directory",[275,344,345],{},"the Python executable path",[275,347,348,351,353,354],{},[278,349,350],{},"Activate the same Python environment used by the app",[282,352],{},"A mismatched virtualenv can point Flask CLI at the wrong dependencies or app module.",[26,355,357],{"className":28,"code":356,"language":30,"meta":31,"style":31},"source \u002Fpath\u002Fto\u002Fvenv\u002Fbin\u002Factivate\nwhich python\nwhich flask\n",[33,358,359,365,373],{"__ignoreMap":31},[36,360,361,363],{"class":38,"line":39},[36,362,50],{"class":49},[36,364,54],{"class":53},[36,366,367,370],{"class":38,"line":46},[36,368,369],{"class":49},"which",[36,371,372],{"class":53}," python\n",[36,374,375,377],{"class":38,"line":57},[36,376,369],{"class":49},[36,378,379],{"class":53}," flask\n",[275,381,382,385,387,388,400,402,403,419,421],{},[278,383,384],{},"Verify Flask CLI can load the application",[282,386],{},"If the app does not load, migration commands may fail or use the wrong context.",[26,389,391],{"className":28,"code":390,"language":30,"meta":31,"style":31},"flask routes\n",[33,392,393],{"__ignoreMap":31},[36,394,395,397],{"class":38,"line":39},[36,396,128],{"class":127},[36,398,399],{"class":53}," routes\n",[282,401],{},"Or verify the app config directly:",[26,404,406],{"className":28,"code":405,"language":30,"meta":31,"style":31},"python -c \"from yourapp import create_app; app=create_app(); print(app.config.get('SQLALCHEMY_DATABASE_URI'))\"\n",[33,407,408],{"__ignoreMap":31},[36,409,410,413,416],{"class":38,"line":39},[36,411,412],{"class":127},"python",[36,414,415],{"class":49}," -c",[36,417,418],{"class":53}," \"from yourapp import create_app; app=create_app(); print(app.config.get('SQLALCHEMY_DATABASE_URI'))\"\n",[282,420],{},"If this fails, fix import errors, missing environment variables, or application factory issues first.",[275,423,424,427,429,430,459,461,462],{},[278,425,426],{},"Check the current migration state",[282,428],{},"Compare the current database revision to the latest migration head.",[26,431,433],{"className":28,"code":432,"language":30,"meta":31,"style":31},"flask db current\nflask db heads\nflask db history\n",[33,434,435,443,451],{"__ignoreMap":31},[36,436,437,439,441],{"class":38,"line":39},[36,438,128],{"class":127},[36,440,131],{"class":53},[36,442,134],{"class":53},[36,444,445,447,449],{"class":38,"line":46},[36,446,128],{"class":127},[36,448,131],{"class":53},[36,450,155],{"class":53},[36,452,453,455,457],{"class":38,"line":57},[36,454,128],{"class":127},[36,456,131],{"class":53},[36,458,165],{"class":53},[282,460],{},"Expected result:",[328,463,464,470,476],{},[275,465,466,469],{},[33,467,468],{},"flask db current"," should report the current revision in the live database",[275,471,472,475],{},[33,473,474],{},"flask db heads"," should report the latest available revision in code",[275,477,478],{},"if they differ, migrations are pending or history is inconsistent",[275,480,481,484,486,487,500,502,503,524,526],{},[278,482,483],{},"Apply pending migrations",[282,485],{},"Run the upgrade against the production database.",[26,488,490],{"className":28,"code":489,"language":30,"meta":31,"style":31},"flask db upgrade\n",[33,491,492],{"__ignoreMap":31},[36,493,494,496,498],{"class":38,"line":39},[36,495,128],{"class":127},[36,497,131],{"class":53},[36,499,186],{"class":53},[282,501],{},"Then verify:",[26,504,506],{"className":28,"code":505,"language":30,"meta":31,"style":31},"flask db current\nflask db heads\n",[33,507,508,516],{"__ignoreMap":31},[36,509,510,512,514],{"class":38,"line":39},[36,511,128],{"class":127},[36,513,131],{"class":53},[36,515,134],{"class":53},[36,517,518,520,522],{"class":38,"line":46},[36,519,128],{"class":127},[36,521,131],{"class":53},[36,523,155],{"class":53},[282,525],{},"The current revision should match the latest head.",[275,528,529,532,534,535,537,538,541,542,544,545,562,564],{},[278,530,531],{},"Inspect failed migrations if upgrade does not complete",[282,533],{},"If ",[33,536,265],{}," fails, inspect the referenced revision file under ",[33,539,540],{},"migrations\u002Fversions\u002F",".",[282,543],{},"Common failure patterns:",[328,546,547,550,553,556,559],{},[275,548,549],{},"duplicate table or column",[275,551,552],{},"missing dependency object",[275,554,555],{},"manual schema drift",[275,557,558],{},"invalid SQL",[275,560,561],{},"insufficient DB permissions",[282,563],{},"Do not generate new migrations in production to work around this. Fix the existing migration path.",[275,566,567,570,572,573,627,629],{},[278,568,569],{},"Validate the database schema directly",[282,571],{},"For PostgreSQL, check the revision table and actual schema objects.",[26,574,576],{"className":28,"code":575,"language":30,"meta":31,"style":31},"psql \"$DATABASE_URL\" -c \"select * from alembic_version;\"\npsql \"$DATABASE_URL\" -c \"\\dt\"\npsql \"$DATABASE_URL\" -c \"\\d your_table_name\"\n",[33,577,578,597,612],{"__ignoreMap":31},[36,579,580,583,586,589,592,594],{"class":38,"line":39},[36,581,582],{"class":127},"psql",[36,584,585],{"class":53}," \"",[36,587,588],{"class":77},"$DATABASE_URL",[36,590,591],{"class":53},"\"",[36,593,415],{"class":49},[36,595,596],{"class":53}," \"select * from alembic_version;\"\n",[36,598,599,601,603,605,607,609],{"class":38,"line":46},[36,600,582],{"class":127},[36,602,585],{"class":53},[36,604,588],{"class":77},[36,606,591],{"class":53},[36,608,415],{"class":49},[36,610,611],{"class":53}," \"\\dt\"\n",[36,613,614,616,618,620,622,624],{"class":38,"line":57},[36,615,582],{"class":127},[36,617,585],{"class":53},[36,619,588],{"class":77},[36,621,591],{"class":53},[36,623,415],{"class":49},[36,625,626],{"class":53}," \"\\d your_table_name\"\n",[282,628],{},"Confirm that expected tables, indexes, and columns now exist.",[275,631,632,635,637,638],{},[278,633,634],{},"Restart application processes after the schema update",[282,636],{},"If your deployment flow requires a reload, restart Gunicorn or your container only after migrations succeed.",[26,639,641],{"className":28,"code":640,"language":30,"meta":31,"style":31},"sudo systemctl restart gunicorn\nsudo systemctl status gunicorn --no-pager\n",[33,642,643,653],{"__ignoreMap":31},[36,644,645,647,649,651],{"class":38,"line":39},[36,646,223],{"class":127},[36,648,226],{"class":53},[36,650,229],{"class":53},[36,652,232],{"class":53},[36,654,655,657,659,661,663],{"class":38,"line":46},[36,656,223],{"class":127},[36,658,226],{"class":53},[36,660,242],{"class":53},[36,662,245],{"class":53},[36,664,248],{"class":49},[275,666,667,670,672,673,675,676],{},[278,668,669],{},"Test the failing path",[282,671],{},"Verify the endpoint, job, or startup path that previously failed.",[282,674],{},"Check for:",[328,677,678,681,684,687],{},[275,679,680],{},"no SQLAlchemy schema errors",[275,682,683],{},"no undefined column errors",[275,685,686],{},"no missing relation errors",[275,688,689],{},"successful app startup",[275,691,692,695,697,698,700,701,752,754,755,541],{},[278,693,694],{},"Prevent the issue in future deploys",[282,696],{},"Add schema upgrades to the deployment sequence before service reload.",[282,699],{},"Example deployment order:",[26,702,704],{"className":28,"code":703,"language":30,"meta":31,"style":31},"git pull\nsource \u002Fpath\u002Fto\u002Fvenv\u002Fbin\u002Factivate\npip install -r requirements.txt\nflask db upgrade\nsudo systemctl restart gunicorn\n",[33,705,706,714,720,734,742],{"__ignoreMap":31},[36,707,708,711],{"class":38,"line":39},[36,709,710],{"class":127},"git",[36,712,713],{"class":53}," pull\n",[36,715,716,718],{"class":38,"line":46},[36,717,50],{"class":49},[36,719,54],{"class":53},[36,721,722,725,728,731],{"class":38,"line":57},[36,723,724],{"class":127},"pip",[36,726,727],{"class":53}," install",[36,729,730],{"class":49}," -r",[36,732,733],{"class":53}," requirements.txt\n",[36,735,736,738,740],{"class":38,"line":64},[36,737,128],{"class":127},[36,739,131],{"class":53},[36,741,186],{"class":53},[36,743,744,746,748,750],{"class":38,"line":70},[36,745,223],{"class":127},[36,747,226],{"class":53},[36,749,229],{"class":53},[36,751,232],{"class":53},[282,753],{},"If your production service fails after migration changes, also review ",[756,757,759],"a",{"href":758},"\u002Ffix-issues\u002Fflask-gunicorn-service-failed-to-start","Flask Gunicorn Service Failed to Start",[18,761,763],{"id":762},"common-causes","Common Causes",[328,765,766,776,787,797,807,813,819,825],{},[275,767,768,775],{},[278,769,770,771,774],{},"Wrong ",[33,772,773],{},"DATABASE_URL"," or environment variables loaded on the server"," → Migrations are applied to a different database than the one Gunicorn uses → Check systemd or Docker environment and compare it to live app config.",[275,777,778,783,784,786],{},[278,779,780,781],{},"Deployment skipped ",[33,782,265],{}," → New code expects schema changes that were never applied → Run ",[33,785,265],{}," as part of the release process before restarting the app.",[275,788,789,792,793,796],{},[278,790,791],{},"Wrong virtualenv or Flask app entrypoint"," → Flask CLI cannot discover the correct app or migration context → Activate the production virtualenv and set ",[33,794,795],{},"FLASK_APP"," correctly.",[275,798,799,802,803,806],{},[278,800,801],{},"Migration files were not deployed"," → Database cannot reach the expected head revision → Deploy the missing ",[33,804,805],{},"migrations\u002Fversions"," files and rerun the upgrade.",[275,808,809,812],{},[278,810,811],{},"Multiple migration heads or branch divergence"," → Alembic cannot determine a single upgrade path → Create and deploy a merge migration.",[275,814,815,818],{},[278,816,817],{},"Manual database changes created schema drift"," → Migration fails with duplicate object or dependency errors → Compare the actual schema to migration logic and reconcile the drift before retrying.",[275,820,821,824],{},[278,822,823],{},"Insufficient database permissions"," → Migration cannot create, alter, or drop objects → Grant the required privileges to the production database user.",[275,826,827,830],{},[278,828,829],{},"Application starts before migrations complete"," → Requests hit the old schema during rollout → Run migrations first, then restart or reload application processes.",[18,832,834],{"id":833},"debugging-section","Debugging Section",[14,836,837],{},"Use these commands to inspect the environment, migration state, service health, and live database.",[26,839,841],{"className":28,"code":840,"language":30,"meta":31,"style":31},"source \u002Fpath\u002Fto\u002Fvenv\u002Fbin\u002Factivate\necho $FLASK_APP\necho $DATABASE_URL\nflask routes\nflask db current\nflask db heads\nflask db history\nflask db upgrade\npython -c \"from yourapp import create_app; app=create_app(); print(app.config.get('SQLALCHEMY_DATABASE_URI'))\"\nsudo systemctl status gunicorn --no-pager\nsudo journalctl -u gunicorn -n 100 --no-pager\nsudo journalctl -u nginx -n 50 --no-pager\npsql \"$DATABASE_URL\" -c \"select * from alembic_version;\"\npsql \"$DATABASE_URL\" -c \"\\dt\"\npsql \"$DATABASE_URL\" -c \"\\d your_table_name\"\n",[33,842,843,849,855,861,867,875,883,891,899,907,919,939,957,971,985],{"__ignoreMap":31},[36,844,845,847],{"class":38,"line":39},[36,846,50],{"class":49},[36,848,54],{"class":53},[36,850,851,853],{"class":38,"line":46},[36,852,294],{"class":49},[36,854,297],{"class":77},[36,856,857,859],{"class":38,"line":57},[36,858,294],{"class":49},[36,860,304],{"class":77},[36,862,863,865],{"class":38,"line":64},[36,864,128],{"class":127},[36,866,399],{"class":53},[36,868,869,871,873],{"class":38,"line":70},[36,870,128],{"class":127},[36,872,131],{"class":53},[36,874,134],{"class":53},[36,876,877,879,881],{"class":38,"line":87},[36,878,128],{"class":127},[36,880,131],{"class":53},[36,882,155],{"class":53},[36,884,885,887,889],{"class":38,"line":100},[36,886,128],{"class":127},[36,888,131],{"class":53},[36,890,165],{"class":53},[36,892,893,895,897],{"class":38,"line":113},[36,894,128],{"class":127},[36,896,131],{"class":53},[36,898,186],{"class":53},[36,900,901,903,905],{"class":38,"line":118},[36,902,412],{"class":127},[36,904,415],{"class":49},[36,906,418],{"class":53},[36,908,909,911,913,915,917],{"class":38,"line":124},[36,910,223],{"class":127},[36,912,226],{"class":53},[36,914,242],{"class":53},[36,916,245],{"class":53},[36,918,248],{"class":49},[36,920,921,923,926,929,931,934,937],{"class":38,"line":137},[36,922,223],{"class":127},[36,924,925],{"class":53}," journalctl",[36,927,928],{"class":49}," -u",[36,930,245],{"class":53},[36,932,933],{"class":49}," -n",[36,935,936],{"class":49}," 100",[36,938,248],{"class":49},[36,940,941,943,945,947,950,952,955],{"class":38,"line":142},[36,942,223],{"class":127},[36,944,925],{"class":53},[36,946,928],{"class":49},[36,948,949],{"class":53}," nginx",[36,951,933],{"class":49},[36,953,954],{"class":49}," 50",[36,956,248],{"class":49},[36,958,959,961,963,965,967,969],{"class":38,"line":148},[36,960,582],{"class":127},[36,962,585],{"class":53},[36,964,588],{"class":77},[36,966,591],{"class":53},[36,968,415],{"class":49},[36,970,596],{"class":53},[36,972,973,975,977,979,981,983],{"class":38,"line":158},[36,974,582],{"class":127},[36,976,585],{"class":53},[36,978,588],{"class":77},[36,980,591],{"class":53},[36,982,415],{"class":49},[36,984,611],{"class":53},[36,986,987,989,991,993,995,997],{"class":38,"line":168},[36,988,582],{"class":127},[36,990,585],{"class":53},[36,992,588],{"class":77},[36,994,591],{"class":53},[36,996,415],{"class":49},[36,998,626],{"class":53},[14,1000,1001],{},"What to look for:",[328,1003,1004,1009,1017,1022,1028,1033],{},[275,1005,1006,1008],{},[33,1007,468],{}," returns no revision or the wrong revision",[275,1010,1011,1013,1014],{},[33,1012,474],{}," shows a newer revision than ",[33,1015,1016],{},"current",[275,1018,1019,1021],{},[33,1020,265],{}," fails on a specific migration file",[275,1023,1024,1027],{},[33,1025,1026],{},"journalctl -u gunicorn"," shows startup failures tied to missing columns or tables",[275,1029,1030,1032],{},[33,1031,261],{}," points to a revision not present in the deployed code",[275,1034,1035],{},"the production schema does not match the code assumptions",[14,1037,1038,1039,541],{},"If Nginx is healthy but Gunicorn is failing due to schema errors, see ",[756,1040,1042],{"href":1041},"\u002Ffix-issues\u002Ffix-flask-502-bad-gateway-step-by-step-guide","Fix Flask 502 Bad Gateway (Step-by-Step Guide)",[18,1044,1046],{"id":1045},"checklist","Checklist",[328,1048,1051,1060,1069,1077,1083,1089],{"className":1049},[1050],"contains-task-list",[275,1052,1055,1059],{"className":1053},[1054],"task-list-item",[1056,1057],"input",{"disabled":60,"type":1058},"checkbox"," Production commands were run in the correct virtualenv or container",[275,1061,1063,1065,1066,1068],{"className":1062},[1054],[1056,1064],{"disabled":60,"type":1058}," ",[33,1067,795],{}," and database environment variables point to the production app",[275,1070,1072,1065,1074,1076],{"className":1071},[1054],[1056,1073],{"disabled":60,"type":1058},[33,1075,468],{}," matches the latest migration head",[275,1078,1080,1082],{"className":1079},[1054],[1056,1081],{"disabled":60,"type":1058}," Required tables and columns exist in the production database",[275,1084,1086,1088],{"className":1085},[1054],[1056,1087],{"disabled":60,"type":1058}," Gunicorn or app containers were restarted after the migration",[275,1090,1092,1094],{"className":1091},[1054],[1056,1093],{"disabled":60,"type":1058}," The failing endpoint or startup path now works without SQL or schema errors",[14,1096,1097,1098,541],{},"For a broader deployment validation pass, use ",[756,1099,1101],{"href":1100},"\u002Fchecklist\u002Fflask-production-checklist-everything-you-must-do","Flask Production Checklist (Everything You Must Do)",[18,1103,1105],{"id":1104},"related-guides","Related Guides",[328,1107,1108,1114,1118,1122],{},[275,1109,1110],{},[756,1111,1113],{"href":1112},"\u002Fdeploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide","Deploy Flask with Nginx + Gunicorn (Step-by-Step Guide)",[275,1115,1116],{},[756,1117,759],{"href":758},[275,1119,1120],{},[756,1121,1042],{"href":1041},[275,1123,1124],{},[756,1125,1101],{"href":1100},[18,1127,1129],{"id":1128},"faq","FAQ",[14,1131,1132,1139,1141,1142,1144],{},[278,1133,1134,1135,1138],{},"Q: Should I run ",[33,1136,1137],{},"flask db migrate"," on the production server?",[282,1140],{},"\nNo. Create and review migrations before deployment, then run ",[33,1143,265],{}," in production.",[14,1146,1147,1153,1155],{},[278,1148,1149,1150,1152],{},"Q: Why does the app still fail after ",[33,1151,265],{}," succeeds?",[282,1154],{},"\nThe service may still be using old code, old environment variables, cached workers, or a different database connection. Verify config and restart the app.",[14,1157,1158,1161,1163],{},[278,1159,1160],{},"Q: What does multiple heads mean in Alembic?",[282,1162],{},"\nIt means migration history branched. You need to create a merge migration so there is a single upgrade path.",[14,1165,1166,1169,1171],{},[278,1167,1168],{},"Q: Can I edit a migration file after it has already been applied in production?",[282,1170],{},"\nAvoid editing applied migrations. Create a new corrective migration instead.",[14,1173,1174,1177,1179,1180,1182,1183,1185],{},[278,1175,1176],{},"Q: How do I confirm the live database matches the migration state?",[282,1178],{},"\nCheck ",[33,1181,468],{},", inspect ",[33,1184,261],{}," directly, and verify the expected tables or columns exist in the production database.",[18,1187,1189],{"id":1188},"final-takeaway","Final Takeaway",[14,1191,1192],{},"Most Flask migration failures in production come from running upgrade commands in the wrong environment or against the wrong database. Confirm the app context, inspect the current Alembic revision, apply the pending upgrade, and verify the live schema before reloading the service.",[1194,1195,1196],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":31,"searchDepth":46,"depth":46,"links":1198},[1199,1200,1201,1202,1203,1204,1205,1206,1207],{"id":20,"depth":46,"text":21},{"id":254,"depth":46,"text":255},{"id":269,"depth":46,"text":270},{"id":762,"depth":46,"text":763},{"id":833,"depth":46,"text":834},{"id":1045,"depth":46,"text":1046},{"id":1104,"depth":46,"text":1105},{"id":1128,"depth":46,"text":1129},{"id":1188,"depth":46,"text":1189},"Complete guide on flask migrations not applied (fix guide) for Flask production environments.","md",{"ogTitle":5,"ogDescription":1208,"twitterCard":1211,"robots":1212,"canonical":1213},"summary_large_image","index, follow","https:\u002F\u002Fflask-deployment.com\u002Ffix-issues\u002Fflask-migrations-not-applied-fix-guide","\u002Ffix-issues\u002Fflask-migrations-not-applied-fix-guide",{"title":5,"description":1208},"fix-issues\u002Fflask-migrations-not-applied-fix-guide","YGPVvasg9l4imSCHCEGGCFiax5F2192oFWh4Ocg0xUE",1776805765845]