Cphalcon: digital field always updated to DB when save model even no value changed actually.

Created on 5 Jan 2019  路  14Comments  路  Source: phalcon/cphalcon

Expected and Actual Behavior

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()

Details

  • Phalcon version: 3.4.2
  • PHP Version: 7.2.11
  • Operating System: macOS 10.14.2
  • Installation type: Compiling from source
  • Zephir version (if any):
  • Server: Apache
  • Other related info (Database, table schema):
not a bug

All 14 comments

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:

https://github.com/niden/cphalcon/blob/T13732-digit-fields/tests/integration/Mvc/Model/FindFirstCest.php#L160

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
1578501141567

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.

Was this page helpful?
0 / 5 - 0 ratings