phinx icon indicating copy to clipboard operation
phinx copied to clipboard

Custom data types (data domain) not working (mysql)

Open kristapsk opened this issue 4 years ago • 4 comments

Tried to create custom data types as per documentation, but they aren't working.

phinx.yml:

paths:
    migrations: '%%PHINX_CONFIG_DIR%%/db/migrations'
    seeds: '%%PHINX_CONFIG_DIR%%/db/seeds'

environments:
    default_migration_table: phinxlog
    default_environment: development
    production:
        adapter: mysql
        host: localhost
        name: production_db
        user: root
        pass: ''
        port: 3306
        charset: utf8

    development:
        adapter: mysql
        host: localhost
        name: phinx_test
        user: phinx_test
        pass: 'phinx_test'
        port: 3306
        charset: utf8

    testing:
        adapter: mysql
        host: localhost
        name: testing_db
        user: root
        pass: ''
        port: 3306
        charset: utf8

version_order: creation

data_domain:
    test_type:
        type: string
        length: 666

Test migration script:

<?php

use Phinx\Migration\AbstractMigration;

class TestMigration extends AbstractMigration
{
    /**
     * Change Method.
     *
     * Write your reversible migrations using this method.
     *
     * More information on writing migrations is available here:
     * https://book.cakephp.org/phinx/0/en/migrations.html
     *
     * The following commands can be used in this method and Phinx will
     * automatically reverse them when rolling back:
     *
     *    createTable
     *    renameTable
     *    addColumn
     *    addCustomColumn
     *    renameColumn
     *    addIndex
     *    addForeignKey
     *
     * Any other destructive changes will result in an error when trying to
     * rollback the migration.
     *
     * Remember to call "create()" or "update()" and NOT "save()" when working
     * with the Table class.
     */
    public function change()
    {
        $this->table('test')
            ->addColumn('test_column', 'test_type')
            ->create();
    }
}

When trying migration, got error:

$ ./vendor/bin/phinx migrate
Phinx by CakePHP - https://phinx.org.

using config file ./phinx.yml
using config parser yml
using migration paths 
 - /home/user/test/phinx/db/migrations
using seed paths 
warning no environment specified, defaulting to: development
using adapter mysql
using database phinx_test
ordering by creation time

 == 20200617223037 TestMigration: migrating
InvalidArgumentException: An invalid column type "test_type" was specified for column "test_column". in /home/user/test/phinx/vendor/robmorgan/phinx/src/Phinx/Db/Table.php:305
Stack trace:
#0 /home/user/test/phinx/db/migrations/20200617223037_test_migration.php(35): Phinx\Db\Table->addColumn()
#1 /home/user/test/phinx/vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php(109): TestMigration->change()
#2 /home/user/test/phinx/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php(377): Phinx\Migration\Manager\Environment->executeMigration()
#3 /home/user/test/phinx/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php(350): Phinx\Migration\Manager->executeMigration()
#4 /home/user/test/phinx/vendor/robmorgan/phinx/src/Phinx/Console/Command/Migrate.php(123): Phinx\Migration\Manager->migrate()
#5 /home/user/test/phinx/vendor/symfony/console/Command/Command.php(258): Phinx\Console\Command\Migrate->execute()
#6 /home/user/test/phinx/vendor/symfony/console/Application.php(911): Symfony\Component\Console\Command\Command->run()
#7 /home/user/test/phinx/vendor/symfony/console/Application.php(264): Symfony\Component\Console\Application->doRunCommand()
#8 /home/user/test/phinx/vendor/robmorgan/phinx/src/Phinx/Console/PhinxApplication.php(69): Symfony\Component\Console\Application->doRun()
#9 /home/user/test/phinx/vendor/symfony/console/Application.php(140): Phinx\Console\PhinxApplication->doRun()
#10 /home/user/test/phinx/vendor/robmorgan/phinx/bin/phinx(28): Symfony\Component\Console\Application->run()
#11 {main}

Using phinx 0.12.1.

kristapsk avatar Jun 17 '20 22:06 kristapsk

I concur, this occurs on Postgres as well. Do you know an ETA to the fix?

` data_domain: varchar: type: string

varchar_req:
    type: string
    'null': 'false'

unique_id:
    type: integer
    identity: true
    seed:   1031
    increment: 13

` When trying migration, got error:

Phinx by CakePHP - https://phinx.org.

using config file ./phinx.yml
using config parser yml
using migration paths 
 - /var/www/db/migrations
using seed paths 
 - /var/www/db/seeds
using environment development
using adapter pgsql
using database visionplanpro
ordering by creation time

 == 20200818150859 AAA: migrating
BEGIN;
InvalidArgumentException: An invalid column type "unique_id" was specified for column "user_id". in /var/www/vendor/robmorgan/phinx/src/Phinx/Db/Table.php:305
Stack trace:
#0 /var/www/db/migrations/20200818150859_a_a_a.php(22): Phinx\Db\Table->addColumn('user_id', 'unique_id')
#1 /var/www/vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php(109): AAA->change()
#```

Phinx 0.12.3

bigeomaha avatar Aug 18 '20 18:08 bigeomaha

In 0.12.5 still broken

piotr-cz avatar Feb 26 '21 19:02 piotr-cz

why doesn't it work? I followed the documentation and wrote a whole list of variables, then discovered this error. Anyway, it's a great way to keep the types used in plain sight. Thanks

Noso4eg avatar May 03 '21 10:05 Noso4eg

Hello, seems this still not working on 0.12.11

However I checked Table::AddColumn() https://github.com/cakephp/phinx/blob/2046c447b1a4425956555118200138e22ebd680c/src/Phinx/Db/Table.php#L300-L304

And it uses AddColumn::build() to build the columns where type $columnName is not an instance of Column however this doesn't do anything with data domains at all

But AdapterInterface does define a method that can create columns from data domains

https://github.com/cakephp/phinx/blob/9a6ce1e7fdf0fa4e602ba5875b5bc9442ccaa115/src/Phinx/Db/Adapter/AdapterInterface.php#L161

I briefly changed the Table::addColumn to use the adapter instead

if ($columnName instanceof Column) {
            $action = new AddColumn($this->table, $columnName);
        } else {
            $action = new AddColumn($this->table, $this->getAdapter()->getColumnForType($columnName, $type, $options));
        }

and it seems to work, I must mention that I didn't fork the project or run tests. Is there a reason this still doesn't work, was there a regression and is now not available to use?

My main goal was to have extra precision on the timestamp for MySQL since Table::addTimestamp doesn't provide a way to add a length/limit to the timestamp type

/// ...SomeMigration.php
$table->addColumn($table->getAdapter()->getColumnForType('created_at', 'created_ts', []));
$table->addColumn($table->getAdapter()->getColumnForType('updated_at', 'created_ts', []));
$table->addColumn($table->getAdapter()->getColumnForType('deleted_at', 'deleted_ts', []));

// phinx.php
'data_domain' => [
        'created_ts' => [
            'type'     => 'timestamp',
            'timezone' => true,
            'length'   => 3,
            'default'  => 'CURRENT_TIMESTAMP(3)'
        ],
        'updated_ts' => [
            'type'     => 'timestamp',
            'timezone' => true,
            'length'   => 3,
            'default'  => 'CURRENT_TIMESTAMP(3)',
            'update'   => 'CURRENT_TIMESTAMP(3)',
            'null'     => true
        ],
        'deleted_ts' => [
            'type'     => 'timestamp',
            'timezone' => true,
            'length'   => 3,
            'null'     => true
        ]
    ]

falmar avatar Jul 15 '22 13:07 falmar

Any update to this issue? Its still not solved..

rikgirbes avatar Dec 14 '22 09:12 rikgirbes

Check if #2156 solves the problem for you.

ndm2 avatar Dec 14 '22 18:12 ndm2

Hey, thanks just tested it out through composer, and it worked using the example I provided above. although the migration ran fine, the created_ts definition does not specify the null option it got created as null it is not mentioned on the docs but I assumed it would pick up the defaults options, manually specifying 'null' => false, worked

falmar avatar Dec 14 '22 18:12 falmar

The default for the null option has been changed for 0.13, it is now true by default. I'm not sure if an explicit default should win over the internal null option default.

You might want to add your input over in #2154, where a possible reversal is currently discussed.

ndm2 avatar Dec 14 '22 19:12 ndm2

#2154

Just tested, works perfectly! Awesome! When will this be merged & released?

(For now I'll just keep your PR as patch, and patch it myself 😊 )

rikgirbes avatar Dec 15 '22 08:12 rikgirbes

Depends on when someone has time to review it. Unfortunately the bulk of this work is currently burdened on pretty much only one person, so it can take a little while.

ndm2 avatar Dec 15 '22 14:12 ndm2