class BaseDatabaseSchemaEditor[source]
Django的遷移系統(tǒng)分為兩個(gè)部分;計(jì)算和儲(chǔ)存應(yīng)該執(zhí)行什么操作的邏輯 (django.db.migrations) ,以及用于把“創(chuàng)建模型”或者“刪除字段”變成SQL語(yǔ)句的數(shù)據(jù)庫(kù)抽象層 -- 后者是模式編輯器的功能。
你可能并不想像一個(gè)普通的開發(fā)者使用Django那樣,直接和模型編輯器進(jìn)行交互,但是如果你編寫自己的遷移系統(tǒng),或者有更進(jìn)一步的需求,這樣會(huì)比編寫SQL語(yǔ)句更方便。
每個(gè)Django的數(shù)據(jù)庫(kù)后端都提供了它們自己的模式編輯器,并且總是可以通過(guò)connection.schema_editor()上下文管理器來(lái)訪問(wèn)。
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(MyModel)
它必須通過(guò)上下文管理器來(lái)使用,因?yàn)檫@樣可以管理一些類似于事務(wù)和延遲SQL(比如創(chuàng)建ForeignKey約束)的東西。
它會(huì)暴露所有可能的操作作為方法,這些方法應(yīng)該按照?qǐng)?zhí)行修改的順序調(diào)用。可能一些操作或者類型并不可用于所有數(shù)據(jù)庫(kù) -- 例如,MyISAM引擎不支持外鍵約束。
如果你在為Django編寫一個(gè)三方的數(shù)據(jù)庫(kù)后端,你需要提供SchemaEditor實(shí)現(xiàn)來(lái)使用1.7的遷移功能 -- 然而,只要你的數(shù)據(jù)庫(kù)在SQL的使用和關(guān)系設(shè)計(jì)上遵循標(biāo)準(zhǔn),你就應(yīng)該能夠派生Django內(nèi)建的SchemaEditor之一,然后簡(jiǎn)單調(diào)整一下語(yǔ)法。同時(shí)也要注意,有一些新的數(shù)據(jù)庫(kù)特性是遷移所需要的:can_rollback_ddl和supports_combined_alters都很重要。
BaseDatabaseSchemaEditor.execute(sql, params=[])[source]
執(zhí)行傳入的 SQL語(yǔ)句,如果提供了參數(shù)則會(huì)帶上它們。這是對(duì)普通數(shù)據(jù)庫(kù)游標(biāo)的一個(gè)簡(jiǎn)單封裝,如果用戶希望的話,它可以從.sql文件中獲取SQL。
BaseDatabaseSchemaEditor.create_model(model)[source]
為提供的模型在數(shù)據(jù)庫(kù)中創(chuàng)建新的表,帶有所需的任何唯一性約束或者索引。
BaseDatabaseSchemaEditor.delete_model(model)[source]
刪除數(shù)據(jù)庫(kù)中的模型的表,以及它帶有的任何唯一性約束或者索引。
BaseDatabaseSchemaEditor.alter_unique_together(model, old_unique_together, new_unique_together)[source]
修改模型的unique_together值;這會(huì)向模型表中添加或者刪除唯一性約束,使它們匹配新的值。
BaseDatabaseSchemaEditor.alter_index_together(model, old_index_together, new_index_together)[source]
修改模型的 index_together值;這會(huì)向模型表中添加或者刪除索引,使它們匹配新的值。
BaseDatabaseSchemaEditor.alter_db_table(model, old_db_table, new_db_table)[source]
重命名模型的表,從old_db_table變成new_db_table。
BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)[source]
把模型的表從一個(gè)表空間移動(dòng)到另一個(gè)中。
BaseDatabaseSchemaEditor.add_field(model, field)[source]
向模型的表中添加一列(或者有時(shí)幾列),表示新增的字段。如果該字段帶有db_index=True或者 unique=True,同時(shí)會(huì)添加索引或者唯一性約束。
如果字段為ManyToManyField并且缺少 through值,會(huì)創(chuàng)建一個(gè)表來(lái)表示關(guān)系,而不是創(chuàng)建一列。如果提供了through值,就什么也不做。
如果字段為ForeignKey,同時(shí)會(huì)向列上添加一個(gè)外鍵約束。
BaseDatabaseSchemaEditor.remove_field(model, field)[source]
從模型的表中移除代表字段的列,以及列上的任何唯一性約束,外鍵約束,或者索引。
如果字段是ManyToManyField并且缺少through值,會(huì)移除創(chuàng)建用來(lái)跟蹤關(guān)系的表。如果提供了through值,就什么也不做。
BaseDatabaseSchemaEditor.alter_field(model, old_field, new_field, strict=False)[source]
這會(huì)將模型的字段從舊的字段轉(zhuǎn)換為新的。這包括列名稱的修改(db_column屬性)、字段類型的修改(如果修改了字段類)、字段NULL狀態(tài)的修改、添加或者刪除字段層面的唯一性約束和索引、修改主鍵、以及修改ForeignKey約束的目標(biāo)。
最普遍的一個(gè)不能實(shí)現(xiàn)的轉(zhuǎn)換,是把ManyToManyField變成一個(gè)普通的字段,反之亦然;Django不能在不丟失數(shù)據(jù)的情況下執(zhí)行這個(gè)轉(zhuǎn)換,所以會(huì)拒絕這樣做。作為替代,應(yīng)該單獨(dú)調(diào)用remove_field()和add_field()。
如果數(shù)據(jù)庫(kù)滿足supports_combined_alters,Django會(huì)盡可能在單次數(shù)據(jù)庫(kù)調(diào)用中執(zhí)行所有這些操作。否則對(duì)于每個(gè)變更,都會(huì)執(zhí)行一個(gè)單獨(dú)的ALTER語(yǔ)句,但是如果不需要做任何改變,則不執(zhí)行ALTER(就像South經(jīng)常做的那樣)。
除非另有規(guī)定,所有屬性都應(yīng)該是只讀的。
SchemaEditor.connection
一個(gè)到數(shù)據(jù)庫(kù)的連接對(duì)象。alias是connection的一個(gè)實(shí)用的屬性,它用于決定要訪問(wèn)的數(shù)據(jù)庫(kù)的名字。
當(dāng)你在多種數(shù)據(jù)庫(kù)之間執(zhí)行遷移的時(shí)候,這是非常有用的。
譯者:Django 文檔協(xié)作翻譯小組,原文:SchemaEditor。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。