time.Time默认值不再是 0001-01-01 00:00:00 了吗? #1066
Comments
@lunny 瞅瞅? |
同时,即使指定了默认值,生成的语句也不是按照默认值来的
生成的语句依然是:
此时,指定了 此时,如果mysql数据的sql_mode设置的是严格模式(一般情况下都是严格模式),这这种日期会被认为是非法的日期,从而导致插入数据库不成功。 |
xorm 生成sql的表现如果这么不可控的话,如果遇上特定sql_mode的设置,更容易出问题。 |
避免这么多不可控因素最好的方案就是,对于 time.Time 的默认值,首先按照 struct tag中定义的 default value来传递,如果struct tag 中没有定义default 值,那么应该采用golang的默认值: '0001-01-01 00:00:00' ,而不是一会儿是 "", 一会又是 interface{}(nil) |
@lunny 来帮忙看看是不是这么个情况?或者可以代码中可以手动指定 session级别的sql_mode? |
升级xorm后,sql中的time.Time默认值变为 interface{}(nil) 因此,目前一个兼容方案是 当 time.Time isZero,插入数据时省略该字段
|
这个地方需要XORM改进,当字段为time.Time类型且IsZero时,如果有默认值则使用默认值,如果没有默认值则为nil |
暂时以你最后那个comment作为临时解决方案 |
没有默认值时,建议最好不要用nil. 原因有三:
第二,如果采用nil为默认值,会导致更新数据库中NOT NULL字段的时候报错“不允许为null” 第三,虽然golang中 '0001-01-01 00:00:00' 和 '0000-00-00 00:00:00' 是一样的,但是在数据库为严格模式下,'0000-00-00' 这类时间会被认为是非法的时间,而'0001-01-01'则不会被认为为非法。 所以,最好的方案是最终还是采用和以前的版本一样的 '0001-01-01 00:00:00',既能保持向后兼容,又能不会受到 sql_mode 的限制。 当然最完美的方案就是,优先按照用户指定的 struct_tag 中的 default value来,用户没有指定,则采用golang的time.Time 的默认值
|
这样可以正常进行, for _, v := range in {
_, err := dstSession.Omit("end_time").Insert(d)
panic(err)
} 但是,这样,任然会报 Error 1048: Column 'end_time' cannot be null _, err := dstSession.Omit("end_time").Insert(in....) 这是为啥??? |
@eleztian 有可能是一个bug |
现在怎么处理啊 |
数据库:
注意:login_time 是NOT NULL
model:
Insert代码:
对于以前的版本(0.5以前?),以上语句不会出错,因为生成的语句是:
而升级到现在的版本后(dep ensure -update):
以上的插入代码会出错,因为生成的语句变成了:
这样导致以前设置了NOT NULL字段的数据表,在插入的时候,会报错:
导致无法完美无缝的将xorm迁移到新版
The text was updated successfully, but these errors were encountered: