easy-swoole / orm

31 stars 27 forks source link

Model插入含有datetime default null字段时, 错误给了空字符串 #41

Closed getchu closed 4 years ago

getchu commented 4 years ago

表结构 CREATE TABLETest` (

id bigint(20) unsigned NOT NULL AUTO_INCREMENT,

phone varchar(13) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '电话号码',

createAt datetime DEFAULT NULL COMMENT '创建时间',

updateAt datetime DEFAULT NULL COMMENT '修改时间',

deleteAt datetime DEFAULT NULL COMMENT '删除时间',

bookDate datetime DEFAULT NULL COMMENT '预约时间'

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='测试表'; `

namespace App\Model;

use EasySwoole\ORM\Utility\Schema\Table;

class Test extends \EasySwoole\ORM\AbstractModel { 指定连接名

//protected $connectionName = 'read';

protected $tableName = "test";

非必选的, 自动时间戳特性, 在插入/更新数据的时候,自动设置设置时间为当前

protected $autoTimeStamp = 'datetime';

protected $createTime = 'createAt';

protected $updateTime = 'updateAt';

}

插入操作 报错,

$info = ["phone" => "0085261234567"];

bookDate字段是选填的,

\App\Model\Test::create($info)->save(true, true);

报错:

SQLSTATE[22007] [1292] Incorrect datetime value: '' for column project.test.bookDate at row 1

代码跟踪:

vendor/easyswoole/orm/src/AbstractModel.php

public function save($notNul = false, $strict = true){

....

$rawArray = $this->toArray($notNul, $strict); 

var_dump($rawArray); 得到 ["bookDate"]=> string(0) "" 不是null ?

}

再找一下 表结构的定义

vendor/easyswoole/orm/src/AbstractModel.php ` public function schemaInfo(bool $isCache = true): Table

{ ........

$tableObjectGeneration = new TableObjectGeneration(DbManager::getInstance()->getConnection($connectionName), $this->tableName);

    $schemaInfo = $tableObjectGeneration->generationTable();

.... } `

进一步找:

https://github.com/easy-swoole/orm/blob/master/src/Utility/TableObjectGeneration.php

vendor/easyswoole/orm/src/Utility/TableObjectGeneration.php ` protected function getTableColumn($column):Column {

    默认值

    if ($column['Default']!==null){

        $columnObj->setDefaultValue($column['Default']);

    }

   ...........

}

`


结论:

SQL:

show full columns from test;

返回的 datetime类型字段, defualt null, 而上方的 默认值判断与赋值 欠佳, 最好改为:

    if ($column['Default']!==null){

        $columnObj->setDefaultValue($column['Default']);

    }else {

        $columnObj->setDefaultValue(null);

   }
xuanyanwow commented 4 years ago

收到 感谢 我们已经安排修复

getchu commented 4 years ago

@xuanyanwow 上面提出的 "结论" 并没有解决问题, 只是修补了另外一个小bug (表结构定义的对象),

这个表结构定义对象 的 defaultValue, 并没有参与到 Model->data 的 初始化,

于是我另辟蹊径, 添加如下代码解决了:

protected function setBookDateAttr($value, $data) {
    if(strlen($value) > 0){
        return $value;
    }else{
        return null;
    }
}

protected function getBookDateAttr($value, $data) {
    if(strlen($value) > 0){
        return $value;
    }else{
        return null;
    }
}
getchu commented 4 years ago

令我不解的是, 这张表, 两个字段 依赖Model 自动填充, 另外两个 defualt null 的 daleteAt和 bookDate 字段 为什么 只有 最后一个bookDate 会报错,而 deleteAt 不抱错

"createAt": "2019-11-23 15:35:00",
 "updateAt": "2019-11-23 15:35:00",
 "deleteAt": null,
"bookDate": null,