When fetch data from db, all digital field(int, bigint, numeric etc.) treated as string(with double quotation marks, example: "99") in models. When finished business logic process, these digital values may changed to real digital value(real int or numeric in php, without double quotation marks, example: 99), then save it, will cause a db write. Actually, it shouldn't write.
SQL schema
DROP TABLE IF EXISTS `demos`;
CREATE TABLE `demos`
(
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`flag` int(10) NOT NULL DEFAULT '1' COMMENT 'Flag',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_520_ci COMMENT ='Demos';
Provide minimal script to reproduce the issue
class Demos extends \Phalcon\Mvc\Model {
}
And there's no attributes defined in model class.
When fetch data
$row = Demos::findFirst(1);
if ( $row ) {
var_dump($row->toArray());
die();
}
will output
array(
'id' => '1',
'flag' => '99'
)
If change the flag value to 99, then save like this:
// other biz codes here
$row->flag = 99;
$row->save();
will trigger a DB write, and can get changed array via getChangedFields()
Post your DI service as well.
According to https://stackoverflow.com/questions/1197005/how-to-get-numeric-types-from-mysql-using-pdo#1197424
add an option to connection config, solved this issue:
'database' => [
// 'adapter' => 'Mysql', /* Possible Values: Mysql, Postgres, Sqlite */
'host' => '127.0.0.1',
'username' => 'root',
'password' => 'root',
'dbname' => 'hcms', // hcms, phalconrestjwt
'port' => 3306,
'charset' => 'utf8mb4',
'options' => [
# https://stackoverflow.com/questions/1197005/how-to-get-numeric-types-from-mysql-using-pdo#1197424
# How to get numeric types from MySQL using PDO?
\PDO::ATTR_EMULATE_PREPARES => false,
],
],
When setup option PDO::ATTR_EMULATE_PREPARES => false
When call $model->save(), true return ,but no record in db table.
@cnyyk Have you tried the orm.cast_on_hydrate option?
Model::setup(
[
'castOnHydrate' => true,
]
);
@cnyyk I do not seem to be able to reproduce this. Please have a look at this test:
It works by returning string as the default. When I set the PDO it returns integers. The same as when I set the castOnHydrate.
Could you have a look and let me know?
Thanks, I'll review this later.
@cnyyk By any change had time to have a look at this?
OK, I'll do some test to verify today.
Thanks.
@ruudboon
Hi, I reported this issue when I was using phalcon 3.4.3 and now using 3.4.5, and not finished the upgrade to 4.0.0.
So I need setup a 4.0.0 test env.
I'll focus on this issue later this week.
@cnyyk thnx. If you need any help upgrading feel free to join us on Discord
@ruudboon
Verified again.
When $row->flag = (int) 99 then do assign $row = '99'; and $row-save();, there's no update query executed on db( via dbProfile). That's pretty good for reducing db write.
And found another issue with low priority, #14690
@niden
Model::setup(
[
'castOnHydrate' => true,
]
);
works like a charm.
but very strangely, there's no description in docs:
https://docs.phalcon.io/3.4/en/db-models#disablingenabling-features

With your guiding and source code of Model.zep, I learned the magic usage.
@cnyyk old docs vs new docs I guess.
https://docs.phalcon.io/4.0/en/db-models#model-features
I am happy we went through all of the docs and added more descriptions and context for v4.
Thanks for verifying this.
That's pretty good. Thanks for the team.