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。

相关文章
相关标签/搜索