Django的資料庫層從Python代碼產生SQL schemas—但是對於遺留資料庫,你已經擁有SQL schemas. 這種情況,你需要為已經存在的資料表建立model. 為此,Django內建了一個可以通過讀取您的資料表結構來產生model的工具. 該協助工具輔助稱為inspectdb,你可以通過執行manage.py inspectdb來調用它.
使用 inspectdb
inspectdb工具自省你設定檔指向的資料庫,針對每一個表產生一個Django模型,然後將這些Python模型的代碼顯示在系統的標準輸出裡面。
下面是一個從頭開始的針對一個典型的遺留資料庫的整合過程。 兩個前提條件是安裝了Django和一個傳統資料庫。
通過運行django-admin.py startproject mysite (這裡 mysite 是你的項目的名字)建立一個Django項目。 好的,那我們在這個例子中就用這個 mysite 作為項目的名字。
編輯項目中的設定檔, mysite/settings.py ,告訴Django你的資料庫連接參數和資料庫名。 具體的說,要提供 DATABASE_NAME , DATABASE_ENGINE , DATABASE_USER , DATABASE_PASSWORD , DATABASE_HOST , 和 DATABASE_PORT 這些配置資訊.。 (請注意其中的一些設定是可選的。 更多資訊參見第5章)
通過運行 python mysite/manage.py startapp myapp (這裡 myapp 是你的應用的名字)建立一個Django應用。 這裡我們使用myapp 做為應用程式名稱。
運行命令 python mysite/manage.py inspectdb。這將檢查DATABASE_NAME 資料庫中所有的表並列印出為每張表產生的模型類。 看一看輸出結果以瞭解inspectdb能做些什麼。
將標準shell的輸出重新導向,儲存輸出到你的應用的 models.py 檔案裡:
python mysite/manage.py inspectdb > mysite/myapp/models.py
編輯 mysite/myapp/models.py 檔案以清理產生的 models 並且做一些必要的自訂。
清理產生的Models
如你可能會預料到的,資料庫自省不是完美的,你需要對產生的模型代碼做些許清理。 這裡提醒一點關於處理產生 models 的要點:
資料庫的每一個表都會被轉化為一個model類 (也就是說,資料庫的表和model 類之間是一對一的映射)。 這意味著你需要為多對多串連的表,重構其models 為 ManyToManyField 的對象。
所產生的每一個model中的每個欄位都擁有自己的屬性,包括id主鍵欄位。 但是,請注意,如果某個model沒有主鍵的話,那麼Django會自動為其增加一個id主鍵欄位。 這樣一來,你也許希望移除這樣的程式碼。
id = models.IntegerField(primary_key=True)
這樣做並不是僅僅因為這些行是冗餘的,而且如果當你的應用需要向這些表中增加新記錄時,這些行會導致某些問題。
每一個欄位類型,如CharField、DateField, 是通過尋找資料庫列類型如VARCHAR,DATE來確定的。如果inspectdb無法把某個資料庫欄位對應到model欄位上,它會使用TextField欄位進行代替,並且會在所產生model欄位後面加入Python注釋“該欄位類型是猜的”。 對這要當心,如果必要的話,更改欄位類型。
如果你的資料庫中的某個欄位在Django中找不到合適的對應物,你可以放心的略過它。 Django模型層不要求必須匯入你資料庫表中的每個列。
如果資料庫中某個列的名字是Python的保留字(比如pass、class或者for等),inspectdb會在每個屬性名稱後附加上_field,並將db_column屬性設定為真實的欄位名(也就是pass,class或者for等)。
例如,某張表中包含一個INT類型的列,其列名為for,那麼所產生的model將會包含如下所示的一個欄位:
for_field = models.IntegerField(db_column='for')
inspectdb 會在該欄位後加註 ‘欄位重新命名,因為它是一個Python保留字' 。
如果資料庫中某張表引用了其他表(正如大多數資料庫系統所做的那樣),你需要適當的修改所產生model的順序,以使得這種引用能夠正確映射。 例如,model Book擁有一個針對於model Author的外鍵,那麼後者應該先於前者被定義。如果你想建立一個指向尚未定義的model的關係,那麼可以使用包含model名的字串,而不是model對象本身。
對於PostgreSQL,MySQL和SQLite資料庫系統,inspectdb能夠自動檢測出主鍵關係。 也就是說,它會在合適的位置插入primary_key=True。 而對於其他資料庫系統,你必須為每一個model中至少一個欄位插入這樣的語句,因為Django的model要求必須擁有一個primary_key=True的欄位。
外鍵檢測僅對PostgreSQL,還有MySQL表中的某些特定類型生效。 至於其他資料庫,外鍵欄位將在假定其為INT列的情況下被自動產生為IntegerField。