當(dāng)你首次建立一個(gè)應(yīng)用的時(shí)候,為你的數(shù)據(jù)庫預(yù)先安裝一些硬編碼的數(shù)據(jù),是很有用處的。 有幾種方法可以讓Django自動(dòng)創(chuàng)建這些數(shù)據(jù):你可以通過fixtures提供初始數(shù)據(jù),或者提供一個(gè)包含初始數(shù)據(jù)的sql文件。
通常來講,使用fixtrue更加簡(jiǎn)潔,因?yàn)樗菙?shù)據(jù)庫無關(guān)的,而使用sql初始化更加靈活。
fixture是數(shù)據(jù)的集合,讓Django了解如何導(dǎo)入到數(shù)據(jù)庫中。創(chuàng)建fixture的最直接的方式,是使用manage.py dumpdata命令,如果數(shù)據(jù)庫中已經(jīng)有了一些數(shù)據(jù)?;蛘吣憧梢允謱慺ixtures。fixtures支持JSON、XML或者YAML(需要安裝PyYAML)文檔。序列化文檔中詳細(xì)闡述了每一種所支持的序列化格式。
下面這個(gè)例子展示了一個(gè)簡(jiǎn)單的Person 模型的fixtrue,看起來很像JSON:
[
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
},
{
"model": "myapp.person",
"pk": 2,
"fields": {
"first_name": "Paul",
"last_name": "McCartney"
}
}
]
下面是它的YAML格式:
- model: myapp.person
pk: 1
fields:
first_name: John
last_name: Lennon
- model: myapp.person
pk: 2
fields:
first_name: Paul
last_name: McCartney
你可以把這些數(shù)據(jù)儲(chǔ)存在你應(yīng)用的fixtures目錄中。
加載數(shù)據(jù)很簡(jiǎn)單:只要調(diào)用manage.py loaddata <fixturename>就好了,其中<fixturename>是你所創(chuàng)建的fixture文件的名字。每次你運(yùn)行l(wèi)oaddata的時(shí)候,數(shù)據(jù)都會(huì)從fixture讀出,并且重復(fù)加載進(jìn)數(shù)據(jù)庫。注意這意味著,如果你修改了fixtrue創(chuàng)建的某一行,然后再次運(yùn)行了 loaddata,你的修改將會(huì)被抹掉。
1.7中廢除:
如果一個(gè)應(yīng)用使用了遷移,將不會(huì)自動(dòng)加載fixtures。由于Django 1.9中,遷移將會(huì)是必要的,這一行為經(jīng)權(quán)衡之后被廢除。 如果你想在一個(gè)應(yīng)用中加載初始數(shù)據(jù),考慮在數(shù)據(jù)遷移中加載它們。
如果你創(chuàng)建了一個(gè)命名為 initial_data.[xml/yaml/json]的fixtrue,在你每次運(yùn)行migrate命令時(shí),fixtrue都會(huì)被加載。這非常方面,但是要注意:記住數(shù)據(jù)在你每次運(yùn)行migrate命令后都會(huì)被刷新。So don’t use initial_data for data you’ll want to edit.
通常,Django 在每個(gè)應(yīng)用的fixtures目錄中尋找fixture文件。你可以設(shè)置FIXTURE_DIRS選項(xiàng)為一個(gè)額外目錄的列表,Django會(huì)從里面尋找。
運(yùn)行manage.py loaddata命令的時(shí)候,你也可以指定一個(gè)fixture文件的目錄,它會(huì)覆蓋默認(rèn)設(shè)置中的目錄。
另見
fixtrues也被用于測(cè)試框架來搭建一致性的測(cè)試環(huán)境。
1.7中廢除:
如果一個(gè)應(yīng)用使用遷移,初始SQL數(shù)據(jù)將不會(huì)加載(包括后端特定的SQL數(shù)據(jù))。由于Django 1.9中,遷移將會(huì)是必須的,這一行為經(jīng)權(quán)衡后被廢除。如果你想在應(yīng)用中使用初始SQL數(shù)據(jù),考慮在數(shù)據(jù)遷移中使用它們。
Django為數(shù)據(jù)庫無關(guān)的SQL提供了一個(gè)鉤子,當(dāng)你運(yùn)行migrate命令時(shí),CREATE TABLE語句執(zhí)行之后就會(huì)執(zhí)行它。你可以使用這個(gè)鉤子來建立默認(rèn)的記錄,或者創(chuàng)建SQL函數(shù)、視圖、觸發(fā)器以及其它。
鉤子十分簡(jiǎn)單:Django會(huì)在你應(yīng)用的目錄中尋找叫做sql/<modelname>.sql的文件,其中 <modelname>是小寫的模型名稱。
所以如果在myapp應(yīng)用中存在Person模型,你應(yīng)該在myapp目錄的文件sql/person.sql中添加數(shù)據(jù)庫無關(guān)的SQL。下面的例子展示了文件可能會(huì)包含什么:
INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');
每個(gè)提供的SQL文件,都應(yīng)該含有用于插入數(shù)據(jù)的有效的SQL語句(例如,格式適當(dāng)?shù)腎NSERT語句,用分號(hào)分隔)。
這些SQL文件可被manage.py中的 sqlcustom和sqlall命令閱讀。詳見manage.py文檔。
注意如果你有很多SQL數(shù)據(jù)文件,他們執(zhí)行的順序是不確定的。唯一可以確定的是,在你的自定義數(shù)據(jù)文件被執(zhí)行之前,所有數(shù)據(jù)表都被創(chuàng)建好了。
初始SQL數(shù)據(jù)和測(cè)試
這一技巧不能以測(cè)試目的用于提供初始數(shù)據(jù)。Django的測(cè)試框架在每次測(cè)試后都會(huì)刷新測(cè)試數(shù)據(jù)庫的內(nèi)容。所以,任何使用自定義SQL鉤子添加的數(shù)據(jù)都會(huì)丟失。
如果你需要在測(cè)試用例中添加數(shù)據(jù),你應(yīng)該在測(cè)試fixture中添加它,或者在測(cè)試用例的setUp()中添加。
沒有鉤子提供給后端特定的SQL數(shù)據(jù)。例如,你有分別為PostgreSQL和SQLite準(zhǔn)備的初始數(shù)據(jù)文件。對(duì)于每個(gè)應(yīng)用,Django都會(huì)尋找叫做<app_label>/sql/<modelname>.<backend>.sql的文件,其中<app_label>是小寫的模型名稱,<modelname>是小寫的模型名稱,<backend>是你的設(shè)置文件中由ENGINE提供的模塊名稱的最后一部分(例如,如果你定義了一個(gè)數(shù)據(jù)庫,ENGINE的值為django.db.backends.sqlite3,Django會(huì)尋找<app_label>/sql/<modelname>.sqlite3.sql)。
后端特定的SQL數(shù)據(jù)會(huì)先于后端無關(guān)的SQL數(shù)據(jù)執(zhí)行。例如,如果你的應(yīng)用包含了sql/person.sql 和sql/person.sqlite3.sql文件,而且你已經(jīng)安裝了SQLite應(yīng)用,Django會(huì)首先執(zhí)行 sql/person.sqlite3.sql的內(nèi)容,其次才是sql/person.sql。