电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Django如何在不停機的情況下創建索引

瀏覽:143日期:2024-09-24 10:39:38

該框架在管理數據庫更改方面非常強大和有用,但是該框架提供的靈活性受到了一定的限制。為了理解Django遷移的局限性,你將處理一個眾所周知的問題:在不停機的情況下,在Django中創建一個索引。

在本教程中,你將學習:

Django如何以及何時生成新的遷移;

如何檢查Django生成的執行遷移的命令;

如何安全地修改遷移以滿足你的需求。

本中級教程是為已經熟悉Django遷移(Migration)的讀者設計的。

在Django遷移中創建索引的問題

當應用程序存儲的數據增長時,通常需要進行的一個常見更改就是添加索引。索引可以用來加快查詢速度,并使你的應用程序運行和響應更快。

在大多數數據庫中,添加索引時需要對表使用獨占鎖。在創建索引時,獨占鎖會防止數據修改(DML)操作,如UPDATE,INSERT,和DELETE。

數據庫在執行某些操作時會隱式地獲取鎖。例如,當用一個戶登錄到你的應用程序時,Django將更新auth_user表中的last_login字段。要執行更新,數據庫首先必須在這個行上獲得一個鎖。如果該行當前被另一個連接鎖定,那么你會得到一個數據庫異常。

當需要在遷移期間保持系統可用時,鎖定表可能會造成問題。表越大,創建索引所需的時間就越長。創建索引所需的時間越長,系統不可用或對用戶無響應的時間就越長。

一些數據庫供應商提供了一種創建索引而不鎖定表的方法。例如,要在PostgreSQL中創建索引而不鎖定表,你可以使用CONCURRENTLY關鍵字:

Django如何在不停機的情況下創建索引

在Oracle中,有一個ONLINE選項允許在創建索引時對表執行DML操作:

Django如何在不停機的情況下創建索引

在生成遷移時,Django不會使用這些特殊的關鍵字。按原樣運行遷移將使數據庫獲得表上的獨占鎖,并在創建索引時防止DML操作。

并發創建索引有一些注意事項。提前了解特定于數據庫后端的問題是很重要的。例如,PostgreSQL中的一個警告是并發創建索引需要更長的時間,因為它需要進行額外的表掃描。

在本教程中,你將使用Django遷移在一個大型表上創建索引,而不會導致任何停機。

注意:要學習本教程,建議你使用PostgreSQL后端,Django2.x和python3。

也可以使用其他數據庫后端。在使用PostgreSQL特有的SQL特性的地方,更改SQL以匹配你的數據庫后端。

設置

你將在一個名為app的應用中使用一個虛構的Sale模型。在現實生活中,Sale等模型是數據庫中的主要表,它們通常會非常大,并存儲大量數據:

Django如何在不停機的情況下創建索引

創建表,生成初始遷移并應用它:

Django如何在不停機的情況下創建索引

一段時間之后,sales表變得非常大,用戶開始抱怨速度太慢。在監視數據庫時,你注意到許多查詢使用sold_at列。為了加快速度,你決定在列上需要一個索引。

要在sold_at上添加索引,你需要對模型進行以下更改:

Django如何在不停機的情況下創建索引

如果按原樣運行這個遷移,那么Django將在表上創建索引,并且它將被鎖定,直到索引完成。在非常大的表上創建索引可能需要一段時間,你希望避免停機。

在具有小數據集和很少連接的本地開發環境中,這種遷移可能是瞬間完成的。然而,對于具有許多并發連接的大型數據集,獲取鎖并創建索引可能需要一段時間。

在接下來的步驟中,你將修改Django創建的遷移,以便在不引起任何停機的情況下創建索引。

偽造遷移

第一種方法是手動創建索引。你將生成遷移,但實際上并不會讓Django應用它。相反,你將在數據庫中手動運行SQL,然后讓Django認為遷移已經完成。

首先,生成遷移:

Django如何在不停機的情況下創建索引

使用sqlmigrate命令來查看Django將用于執行此遷移的SQL:

Django如何在不停機的情況下創建索引

你希望在不鎖定表的情況下創建索引,因此你需要修改命令。添加CONCURRENTLY關鍵字并在數據庫中執行:

Django如何在不停機的情況下創建索引

注意,你在執行命令的過程中沒有BEGIN和COMMIT部分。省略這些關鍵字會在沒有數據庫事務的情況下執行命令。我們將在本文后面討論數據庫事務。

執行命令后,如果你嘗試應用遷移,會出現以下錯誤:

Django如何在不停機的情況下創建索引

Django會提示你該索引已經存在,因此無法繼續遷移。你剛剛在數據庫中直接創建了索引,所以現在需要讓Django認為已經應用了遷移。

如何偽造一個遷移

Django提供了一種內置的方法,可以將遷移標記為已執行,而不需要實際執行它們。要使用這個選項,你需要在應用遷移時設置—fake標志:

Django如何在不停機的情況下創建索引

這一次Django沒有拋出錯誤。實際上,Django并沒有真正應用任何遷移。它只是將其標記為已執行(或FAKED)。

以下是在偽造遷移時需要考慮的一些問題:

手動命令必須與Django生成的SQL等價: 你需要確保所執行的命令與Django生成的SQL等價。使用sqlmigrate來生成SQL命令。如果命令不匹配,則可能導致數據庫和模型狀態之間的不一致。

其他未應用的遷移也將被偽造:當你有多個未應用的遷移時,它們都將被偽造。在應用遷移之前,重要的是確保只有你想要偽造的遷移沒有應用。否則,你可能會得到不一致的結果。另一個選項是指定要偽造的確切遷移。

需要直接訪問數據庫:你需要在數據庫中運行SQL命令,這有時也不是必需的。此外,在生產數據庫中直接執行命令是危險的,應該盡可能避免。

自動化部署流程可能需要調整:如果你自動化了部署流程(使用CI、CD或其他自動化工具),那么你可能需要將流程更改為偽遷移。這并不總是可取的。

清理

在繼續下一節之前,你需要將數據庫恢復到它在初始遷移之后的狀態。要做到這一點,請遷移回初始遷移:

Django如何在不停機的情況下創建索引

Django沒有應用在第二次遷移中所做的更改,所以現在可以安全地刪除文件:

Django如何在不停機的情況下創建索引

為了確保你做的一切都是正確的,檢查一下遷移:

Django如何在不停機的情況下創建索引

應用了初始遷移之后,就沒有未應用的遷移了。

在遷移(Migration)中執行原始SQL

在上一節中,你直接在數據庫中執行SQL并偽造遷移。這樣就完成了任務,但是還有一個更好的解決方案。

Django提供了一種使用RunSQL在遷移中執行原始SQL的方法。我們來嘗試使用它代替直接在數據庫中執行命令。

首先,生成一個新的空遷移:

Django如何在不停機的情況下創建索引

接下來,編輯遷移文件并添加RunSQL操作:

Django如何在不停機的情況下創建索引

當你運行遷移時,你將獲得以下輸出:

Django如何在不停機的情況下創建索引

這看起來不錯,但有一個問題。我們再次來嘗試生成遷移:

Django如何在不停機的情況下創建索引

Django再次生成了相同的遷移。為什么會這樣?

清理

在回答這個問題之前,你需要清理并撤消對數據庫所做的更改。首先刪除最后一次遷移。它沒有被應用,所以可以安全刪除:

Django如何在不停機的情況下創建索引

接下來,列出app應用程序的遷移:

Django如何在不停機的情況下創建索引

第三次遷移已經結束,但是只應用了第二次遷移。你希望回到初始遷移之后的狀態。試著像你在上一節所做的那樣遷移回初始遷移狀態:

Django如何在不停機的情況下創建索引

Django無法進行逆向遷移。

逆向遷移操作

要進行一次逆向遷移,Django會對每個操作執行相反的操作。在本例中,添加索引的反面是刪除索引。正如你已經看到的,當一個遷移是可逆的時,你可以取消應用它。就像你可以在Git中使用checkout一樣,如果你對較早的遷移執行了migrate命令,你可以進行逆向遷移。

許多內置遷移操作已經定義了反向操作。例如,添加字段的反向操作是刪除對應的列,創建模型的反向操作是刪除相應的表。

有些遷移操作是不可逆的。例如,刪除字段或刪除模型沒有反向操作,因為一旦應用了遷移,數據就會消失。

在上一節中,你使用了RunSQL操作。當你試圖進行反向遷移時,遇到了一個錯誤。根據錯誤提示,遷移中的一個操作不能逆轉。Django默認情況下無法反轉原始SQL。因為Django不知道該操作執行了什么,所以它不能自動生成相反的操作。

如何使遷移可逆

要使一個遷移是可逆的,遷移中的所有操作都必須是可逆的。只逆轉遷移的一部分是不可能的,因此一個單一的不可逆操作將使整個遷移不可逆。

要使RunSQL操作可逆,你必須提供在操作反轉時執行的SQL。反向SQL在reverse_sql參數中提供。

添加索引的相反操作是刪除索引。要使你的遷移可逆,請提供reverse_sql參數來刪除索引:

Django如何在不停機的情況下創建索引

現在試著反轉遷移:

Django如何在不停機的情況下創建索引

我們對第二次遷移進行了反轉,Django刪除了索引。現在可以安全地刪除遷移文件了:

Django如何在不停機的情況下創建索引

提供reverse_sql總是一個好主意。在反轉原始SQL操作而不需要其他任何操作的情況下,你可以使用特殊的哨兵語句migrations.

RunSQL.noop將該操作標記為可逆操作。

Django如何在不停機的情況下創建索引

理解模型狀態和數據庫狀態

在你之前嘗試使用RunSQL手動創建索引時,Django一次又一次地生成了相同的遷移,盡管索引是在數據庫中創建的。要理解Django為什么這樣做,你首先需要理解Django如何決定何時生成新的遷移。

當Django生成一個新的遷移時

在生成和應用遷移的過程中,Django同步數據庫狀態和模型狀態。例如,當你向模型添加字段時,Django會向表添加一列。當你從模型中刪除字段時,Django將從表中刪除列。

為了在模型和數據庫之間同步,Django擁有一個表示模型的狀態。為了使數據庫與模型同步,Django會生成遷移操作。遷移操作轉換為可以在數據庫中執行的特定供應商的SQL。當所有遷移操作都執行后,數據庫和模型應該是一致的。

為了獲得數據庫的狀態,Django聚合了所有過去遷移的操作。當遷移的聚合狀態與模型的狀態不一致時,Django會生成一個新的遷移。

在前面的例子中,你使用原始SQL創建了索引。Django不知道你創建了索引,因為你沒有使用熟悉的遷移操作。

當Django聚合所有遷移并將它們與模型的狀態進行比較時,它發現缺少一個索引。這就是為什么即使你手動創建了索引,Django仍然認為它是缺失的,并為它生成了一個新的遷移。

如何在遷移中分離數據庫和狀態

由于Django無法按照你希望的方式創建索引,所以你希望提供自己的SQL,但仍然要讓Django知道你已經創建了索引。

換句話說,你需要在數據庫中執行一些操作,并為Django提供遷移操作來同步其內部狀態。為此,Django為我們提供了一個名為 SeparateDatabaseAndState的特殊遷移操作。這項操作并不為人所知,應該留到像這種特殊情況下使用。

編輯遷移要比從頭開始寫容易的多,因此,首先以通常的方式生成一個遷移:

Django如何在不停機的情況下創建索引

這是Django生成的遷移內容,和之前一樣:

Django如何在不停機的情況下創建索引

Django在字段sold_at上生成了一個AlterField操作。該操作會創建一個索引并更新狀態。我們希望保留這個操作,但是在數據庫中提供一個不同的命令來執行。

同樣,要獲得該命令,請使用Django生成的SQL:

Django如何在不停機的情況下創建索引

在合適的地方添加CONCURRENTKY關鍵字:

Django如何在不停機的情況下創建索引

接著,編輯該遷移文件,并使用SeparateDatabaseAndState來提供你修改過的SQL命令并執行:

Django如何在不停機的情況下創建索引

遷移操作separate atabaseandstate接受2個操作列表:

1.state_operations是應用于內部模型狀態的操作。它們不會影響數據庫。

2.database_operations是應用于數據庫的操作。

你在state_operations中保留了Django生成的原始操作。當使用SeparateDatabaseAndState時,這是你通常想要做的,注意向字段提供db_index=True參數。這個遷移操作將讓Django知道字段上有一個索引。

你使用了Django生成的SQL并添加了CONCURRENTLY關鍵字。你使用特殊的操作RunSQL來在遷移中執行原始SQL。

如果你試圖運行此遷移,你將獲得以下輸出:

Django如何在不停機的情況下創建索引

非原子遷移

在SQL中,CREATE、DROP、ALTER和TRUNCATE操作稱為數據定義語言(Data Definition Language, DDL)。在支持事務性DDL的數據庫中,比如PostgreSQL,Django默認會在數據庫事務中執行遷移。然而,根據上面的錯誤,PostgreSQL不能在事務塊中并發地創建索引。

為了能夠在遷移中并發地創建索引,你需要告訴Django不要在數據庫事務中執行遷移。為此,通過將atomic設置為False,將遷移標記為非原子(non-atomic):

Django如何在不停機的情況下創建索引

將遷移標記為非原子之后,你可以運行遷移了:

Django如何在不停機的情況下創建索引

你只是執行了遷移,并沒有引起任何停機。

下面是使用SeparateDatabaseAndState時需要考慮的一些問題

數據庫操作必須與狀態操作等價:數據庫和模型狀態之間的不一致可能會造成很多麻煩。一個好的開始是保留Django在 state_operations中生成的操作和編輯sqlmigrate的輸出并在database_operations中使用。

非原子遷移在發生錯誤時不能回滾:如果在遷移過程中出現錯誤,則無法回滾。你必須要么回滾遷移,要么手動完成它。將在非原子遷移中執行的操作保持在最少是一個好主意。如果你在遷移中有其他操作,請將它們移到新的遷移中。

遷移可能是特定于供應商的:Django生成的SQL特定于項目中使用的數據庫后端。它可能會在其他數據庫后端運行,但這并不能保證。如果你需要支持多個數據庫后端,則需要對這種方法進行一些調整。

結論:

你從一個大型的數據表和一個問題開始了本教程。你想讓你的應用程序對用戶來說更快,你想在不引起應用程序任何停機的情況下做到這一點。

在本教程的最后,你嘗試生成并安全地修改了一個Django遷移來實現這一目標。在此過程中,你遇到了不同的問題,并使用migration 框架提供的內置工具設法解決了這些問題。

在本教程中,你學習了以下內容:

Django遷移在內部如何使用模型和數據庫狀態進行工作,以及何時生成新的遷移; 如何使用RunSQL操作在遷移中執行自定義的SQL; 什么是可逆遷移,以及如何使RunSQL操作可逆; 什么是原子遷移,以及如何根據需要更改默認行為; 如何安全地在Django中執行復雜的遷移。

模型與數據庫狀態的分離是一個重要的概念。一旦你理解了它,以及知道如何使用它,你就可以突破內置遷移操作的許多限制。我想到的一些用例包括添加已經在數據庫中創建的索引,以及為DDL命令提供特定的服務商參數。

到此這篇關于Django如何在不停機的情況下創建索引的文章就介紹到這了,更多相關不停機狀態下使用Django創建索引內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Django
相關文章:
主站蜘蛛池模板: 洁净棚-洁净工作棚-无菌室-净化工程公司_北京卫护科技有限公司 | GAST/BRIWATEC/CINCINNATI/KARL-KLEIN/ZIEHL-ABEGG风机|亚喜科技 | 医疗仪器模块 健康一体机 多参数监护仪 智慧医疗仪器方案定制 血氧监护 心电监护 -朗锐慧康 | 圆周直径尺-小孔内视镜-纤维研磨刷-东莞市高腾达精密工具 | 南京租车,南京汽车租赁,南京包车,南京会议租车-南京七熹租车 | cnc精密加工_数控机械加工_非标平键定制生产厂家_扬州沃佳机械有限公司 | 中图网(原中国图书网):网上书店,尾货特色书店,30万种特价书低至2折! | 切铝机-数控切割机-型材切割机-铝型材切割机-【昆山邓氏精密机械有限公司】 | 厂房出租-厂房规划-食品技术-厂房设计-厂房装修-建筑施工-设备供应-设备求购-龙爪豆食品行业平台 | 2025世界机器人大会_IC China_半导体展_集成电路博览会_智能制造展览网 | 电销卡_北京电销卡_包月电话卡-豪付网络 | 液压油缸生产厂家-山东液压站-济南捷兴液压机电设备有限公司 | 钢绞线万能材料试验机-全自动恒应力两用机-混凝土恒应力压力试验机-北京科达京威科技发展有限公司 | 冷柜风机-冰柜电机-罩极电机-外转子风机-EC直流电机厂家-杭州金久电器有限公司 | 韦伯电梯有限公司| 电磁流量计_智能防腐防爆管道式计量表-金湖凯铭仪表有限公司 | 论文查重_免费论文查重_知网学术不端论文查重检测系统入口_论文查重软件 | 一体化污水处理设备_生活污水处理设备_全自动加药装置厂家-明基环保 | 卧涛科技有限公司科技项目申报公司|高新技术企业申报|专利申请 | 福兰德PVC地板|PVC塑胶地板|PVC运动地板|PVC商用地板-中国弹性地板系统专业解决方案领先供应商! 福建成考网-福建成人高考网 | 金属检测机_金属分离器_检针验针机_食品药品金属检探测仪器-广东善安科技 | 背压阀|减压器|不锈钢减压器|减压阀|卫生级背压阀|单向阀|背压阀厂家-上海沃原自控阀门有限公司 本安接线盒-本安电路用接线盒-本安分线盒-矿用电话接线盒-JHH生产厂家-宁波龙亿电子科技有限公司 | 苏州注册公司_苏州代理记账_苏州工商注册_苏州代办公司-恒佳财税 | 企业彩铃制作_移动、联通、电信集团彩铃上传开通_彩铃定制_商务彩铃管理平台-集团彩铃网 | 济南冷库安装-山东冷库设计|建造|冷库维修-山东齐雪制冷设备有限公司 | 金属切削液-脱水防锈油-电火花机油-抗磨液压油-深圳市雨辰宏业科技发展有限公司 | 耐火浇注料-喷涂料-浇注料生产厂家_郑州市元领耐火材料有限公司 耐力板-PC阳光板-PC板-PC耐力板 - 嘉兴赢创实业有限公司 | 马尔表面粗糙度仪-MAHR-T500Hommel-Mitutoyo粗糙度仪-笃挚仪器 | 中空玻璃生产线,玻璃加工设备,全自动封胶线,铝条折弯机,双组份打胶机,丁基胶/卧式/立式全自动涂布机,玻璃设备-山东昌盛数控设备有限公司 | 滚筒线,链板线,总装线,流水线-上海体能机电有限公司 | 金属抛光机-磁悬浮抛光机-磁力研磨机-磁力清洗机 - 苏州冠古科技 | 厌氧工作站-通用型厌氧工作站-上海胜秋科学仪器有限公司 | 旗帜网络笔记-免费领取《旗帜网络笔记》电子书| 临朐空调移机_空调维修「空调回收」临朐二手空调 | 压片机_高速_单冲_双层_花篮式_多功能旋转压片机-上海天九压片机厂家 | 自动检重秤-动态称重机-重量分选秤-苏州金钻称重设备系统开发有限公司 | 保定市泰宏机械制造厂-河北铸件厂-铸造厂-铸件加工-河北大件加工 | 细沙回收机-尾矿干排脱水筛设备-泥石分离机-建筑垃圾分拣机厂家-青州冠诚重工机械有限公司 | 阻垢剂-反渗透缓蚀阻垢剂厂家-山东鲁东环保科技有限公司 | 杭州画室_十大画室_白墙画室_杭州美术培训_国美附中培训_附中考前培训_升学率高的画室_美术中考集训美术高考集训基地 | 【电子厂招聘_普工招工网_工厂招聘信息平台】-工立方打工网 |