uliweb中ORM的nullable和server default的處理

在uliweb 0.2版本之前,在定義ORM Model時,咱們能夠在定義某個字段時傳入 nullable, server_default 參數。nullable爲True或False分別表示取值能夠爲null或不爲null。server_default 實際上是底層的sqlalchemy的一個參數,它的做用是在表示時添加DEFAULT內容。下面分別說一下。mysql

對於nullable,若是定義爲False,則在建表時,將會使用 NOT NULL信息,這樣就表示你不能向這個字段添加null值。在mysql的索引中,若是值爲null是不會將其內容加到索引中的。因此不少狀況下,在建表時都會指明是NOT NULL。那麼在0.2以前,缺省的nullable=True。在0.2版,我將其改成了False。因此這是一個很大的變化。這種變化會影響如今已經在存的應用。若是你的某個字段值已經存在爲null的,將表結構修改成NOT NULL會由於沒法將null轉爲其它的合法值而形成alter table失敗。因此,爲了讓現存的應用還保持原來的配置,在uliweb.contrib.orm的settings.ini中添加了新的ORM的配置項: NULLABLE. 它是一個全局的配置。當沒有在定義字段時傳入nullable參數時,它將起做用。所以,若是你想保持原來的方式,能夠在 settings.ini 中設置它爲True。web

對於server_default,缺省爲None,則不會生成DEFAULT信息。這裏對於mysql數據庫有一些限制:sql

  • TEXT, BLOB 字段類型不支持DEFAULT
  • FLOAT類型應定義爲 0
  • DATETIME, DATE, TIME的缺省爲能夠分別爲: 0000-00-00 00:00:00 , 0000-00-0000:00:00 。在處理時,仍然可使用 date is null來查詢。

對於在使用SQLAlchemy來定義server_default時,象 0這樣的值,不能直接寫 server_default=0 ,而是要:數據庫

from sqlalchemy.sql import text
... server_default=text('0')

這樣,生成的sql語句會是 : DEFAULT 0測試

若是是一個簡單的字符串,如: server_default='' 會轉爲 DEFAULT ''code

在ORM的配置中,也添加了這樣一個全局配置, ORM/SERVER_DEFAULT 。缺省爲 False。所以你能夠在settings.ini中修改它。orm

在大多數狀況下nullable和 server_default 是須要聯用的。在測試中發現,若是一個字段定義爲not null,可是在insert時沒有給出時確的值時,若是不定義 server_default,這時數據庫會報錯。通過查看mysql的文檔,這是和mysql的 sql_mode 有關係的。 sql_mode 有許多的值,我查了我本地的定義是:STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 。其中第一個表示嚴格模式,它會當沒有給出缺省值,而字段又是NOT NULL時報錯。其實也可讓Mysql自動根據數據類型給出一個缺省值,能夠手工修改這個 sql_mode 。所以爲了減小錯誤,uliweb提供了 server_default 的自動生成,前提是你打開了 SERVER_DEFAULT 的開關項。固然,手工傳也是能夠的。server

其實對於沒有給值,在開發時仍是很容易發現的。最主要的問題就是在修改表結構時,當咱們修改了某個字段的 nullableserver_default 屬性時,若是處理很差,會有不少不指望的值,好比一個integer類型的值多是null,但同時又要求它not null,那麼經過設置 server_default 會比較好的解決這個問題。sqlalchemy

所以請注意這兩個ORM相關的配置項索引

NULLABLE = False
SERVER_DEFAULT = False

第一個爲了和之前的兼容,能夠改成True。

相關文章
相關標籤/搜索