20

I'm getting following error "Cannot process definition to array for type tinytext" on Magento 2.3.0 when executing php bin/magento setup:upgrade command.

Thanks

3
  • Has a solution already been found? I have the same problem. Thanks Chris
    – Christoph
    Commented Dec 1, 2018 at 12:16
  • This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. - From Review
    – sv3n
    Commented Dec 1, 2018 at 13:04
  • Checkout this blog, it's really working armmage.com/2021/12/01/…
    – ArmMage
    Commented Dec 14, 2021 at 10:34

10 Answers 10

51

You are getting this error because "data type" of any third-party extension's table's column is tinytext.

Note: Normally this error happens because of Fishpig Wordpress extension's wp_comment table has tinytext data type

So you need to find out the column name in the following file.

Go to this file /vendor/magento/framework/Setup/Declaration/Schema/Db/DefinitionAggregator.php and see this fromDefinition() method and then debug to find column name.

public function fromDefinition(array $data)
    {
        $type = $data['type'];
        if (!isset($this->definitionProcessors[$type])) {

            /* Add Code for Debug */

            echo "<pre>";
            print_r($data); exit();

            /* Code End */

            throw new \InvalidArgumentException(
                sprintf("Cannot process definition to array for type %s", $type)
            );
        }

        $definitionProcessor = $this->definitionProcessors[$type];
        return $definitionProcessor->fromDefinition($data);
    }

After that please run setup:upgrade command and you will get an array of column data in the console. so from this array, you will get the name of the column from your third party extension table.

Now from that table please change column's data type "tinytext" to "text" and issue will be fixed.

SECOND METHOD

Please export the database and search for keywords tinytext, you will found a table which uses this format, Now changed it to TEXT and the problem solved.

THIRD METHOD

The easiest and most secure fix is to install WordPress in a separate database to Magento.

This prevents Magento from applying it's DB schema system to the WordPress database and if you use separate DB users as well, it also has the added benefit of being more secure.

Note: You might also get issues from ENUM, TIME and MEDIUMINT data type as well, so do the same steps if get any other data type issue.

4
  • thanks for your clue. i had found that colum and i am sharing the answer how i resolved. +1 vote Commented Dec 5, 2018 at 9:38
  • 3
    This is clearly a regression and a bug. Any table declared in the magento database with a type of ENUM, TINYTEXT or MEDIUMINT will cause this problem even if it's not managed by magento. It should be possible to have magento and wordpress share the same database. They even suppord table prefixes for this reason. Has a bug been reported about this? Commented Dec 14, 2018 at 23:52
  • @PradeepSanku please accept my ans if its usefull to you, so it will help others for this type of issues. and let me know if you have any question. Thanks! Commented Dec 31, 2018 at 5:37
  • Thank you this saved us! Ultimately I removed the exit() in the debug code, and closed the <pre>, I left it there. Also I exported the clients DB (with no content), then searched for the word "mediumint" (the offending definition in my case) and found a table that had 2 of those, a WordPress plugin (from Fishpig)! Changed the mediumint columns to int in the db. Works again!!!
    – P_V
    Commented Sep 18 at 14:57
14

In my case, Wordpress was being used with the Fishpig integration. In wp_comments, the comment_author was set to TINYTEXT. The problem was resolved by changing that column declaration.

2
  • 1
    Thanks! This is the exact answer that I want! It worked on my end. Commented Apr 25, 2019 at 6:09
  • Yes, Working this one. Thanks. Commented Nov 23, 2020 at 12:45
9

If you do WordPress migrations frequently, changing the schema as suggested in some of the other answers is tedious and easy to forget, plus changing the schema seems hacky. To resolve this, I wrote a small plugin (Interceptor) so that Magento would ignore the WordPress Tables.

Per the docs, using "Around" Interceptors is not ideal, but in this particular case it seems fair - we'd just need to keep an eye on any changes to this method since we are completely replacing it.

Package/Module/etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Setup\Declaration\Schema\Db\MySQL\DbSchemaReader">
        <plugin name="your-plugin-name" type="\Package\Module\Plugin\DbSchemaReaderPlugin" sortOrder="1" disabled="false"/>
    </type>
</config>

Package/Module/Plugin/DbSchemaReaderPlugin.php

namespace Package\Module\Plugin;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Setup\Declaration\Schema\Db\DefinitionAggregator;
use Magento\Framework\Setup\Declaration\Schema\Db\MySQL\DbSchemaReader;

class DbSchemaReaderPlugin
{

    const WP_PREFIX = 'wp_'; //or switch to your prefix.

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;

    /**
     * @var DefinitionAggregator
     */
    private $definitionAggregator;

    /**
     * Constructor.
     *
     * @param ResourceConnection   $resourceConnection
     * @param DefinitionAggregator $definitionAggregator
     */
    public function __construct(
        ResourceConnection $resourceConnection,
        DefinitionAggregator $definitionAggregator
    ) {
        $this->resourceConnection   = $resourceConnection;
        $this->definitionAggregator = $definitionAggregator;
    }


    /**
     * @param DbSchemaReader $subject
     * @param callable $proceed 
     * @param string $resource Argument from the original method call.
     *
     * @return array
     */
    public function aroundReadTables(
        DbSchemaReader $subject,
        callable $proceed,
        $resource
    ) {
        $adapter = $this->resourceConnection->getConnection($resource);
        $dbName  = $this->resourceConnection->getSchemaName($resource);
        $stmt    = $adapter->select()
                           ->from(
                               ['information_schema.TABLES'],
                               ['TABLE_NAME']
                           )
                           ->where('TABLE_SCHEMA = ?', $dbName)
                           ->where('TABLE_TYPE = ?', DbSchemaReader::MYSQL_TABLE_TYPE)
                           ->where('TABLE_NAME NOT LIKE "'.self::WP_PREFIX.'%"');

        return $adapter->fetchCol($stmt);
    }
}
3
  • Perfect solution for wordpress user!
    – MageLerner
    Commented Dec 5, 2019 at 14:36
  • This one really works! It is ignoring WordPress tables upon running setup: upgrade Thanks for this! Commented Jul 14, 2020 at 16:03
  • 1
    Really great solution, thanks Phil Commented Dec 2, 2021 at 16:49
2

A handy little SQL script if anyone wants to know which columns have tinytext types defined.

SELECT TABLE_NAME,
   `COLUMNS`.`COLUMN_NAME`                       AS `name`, `COLUMNS`.`COLUMN_DEFAULT` AS `default`,
   `COLUMNS`.`DATA_TYPE`                         AS `type`, IF(IS_NULLABLE = "YES", true, false) AS `nullable`,
   `COLUMNS`.`COLUMN_TYPE`                       AS `definition`, `COLUMNS`.`EXTRA` AS `extra`,
   IF(COLUMN_COMMENT = "", NULL, COLUMN_COMMENT) AS `comment`
FROM `information_schema`.`COLUMNS`
WHERE (TABLE_SCHEMA = '<table_schema>') AND (`COLUMNS`.`DATA_TYPE` = 'tinytext');

Helped me find the offending third-party module quickly.

2
  • 2
    or just 'SELECT t.* FROM information_schema.COLUMNS t WHERE DATA_TYPE = 'tinytext''
    – asherrard
    Commented Jan 22, 2020 at 23:50
  • Yeah if you are ok with heaps of fields in the output and want the output for all schemas that user has access to sure. Commented Jan 23, 2020 at 2:09
2

For users of the FishPig WP module you can resolve the problem with the following mysql query:

ALTER TABLE wp_comments MODIFY comment_author VARCHAR(250);

1

Magento 2.3 developers will not add support for tinytext data type. varchar type is recommended to use instead of tinytext.

2
  • What about TIME? Commented Mar 8, 2019 at 1:02
  • sorry, I have no info about TIME :(
    – Alex Gusev
    Commented Mar 8, 2019 at 14:24
1

I have faced same issue and getting solution using below step.

Open this file

/vendor/magento/framework/Setup/Declaration/Schema/Db/DefinitionAggregator.php

Find function fromDefinition()

add echo "<pre>";print_r($data); exit(); line like

public function fromDefinition(array $data) {
    $type = $data['type'];
    if (!isset($this->definitionProcessors[$type])) {
        echo "<pre>";print_r($data); exit();
        throw new \InvalidArgumentException(
            sprintf("Cannot process definition to array for type %s", $type)
        );
    }

    $definitionProcessor = $this->definitionProcessors[$type];
    if (isset($data['default'])) {
        $data['default'] = $this->processDefaultValue($data);
    }

    return $definitionProcessor->fromDefinition($data); }

You will get in print_r like this

Array
(
    [name] => IsRoot
    [default] =>
    [type] => bit
    [nullable] => 0
    [definition] => bit(1)
    [extra] =>
    [comment] =>
)

Now Find the "IsRoot" column in your DB using the below query

SELECT table_name, column_name from information_schema.columns WHERE column_name LIKE '%IsRoot%';

After executing the query you can find a table where the "IsRoot" column is defined. Now check the column type.

If the column type is bit then please change the column type using

ALTER TABLE tablename MODIFY IsRoot VARCHAR(250);

Now run the php bin/magento s:up command and check your issue is resolved.

0

We've made a quick composer patch to tell the Magento declarative schema validator to ignore WordPress. Obviously this only fixes the issue if wordpress is the culprit.

You can see the patch here: https://www.cadence-labs.com/2019/08/magento-2-3-wordpress-fix-cannot-process-definition-to-array-for-type-tinytext/

0

All of these answers work, but the easiest and most secure fix is to install WordPress in a separate database to Magento.

This prevents Magento from applying it's DB schema system to the WordPress database and if you use separate DB users as well, it also has the added benefit of being more secure.

0

I got a similar error on a brand new install of magento 2.3.7

Using MAMP on mac
Went to localhost
phpadmin
databases
type in database name 'magento2'
click create (to create new db table)
switch back to magento cli

$ bin/magento setup:install
--base-url=http://127.0.0.1/magento2/
--db-host=127.0.0.1
--db-name=magento2
--db-user=root
--db-password=root
--admin-firstname=Magento
--admin-lastname=User
[email protected]
--admin-user=admin
--admin-password=admin123
--language=en_US
--currency=USD
--timezone=America/Chicago
--use-rewrites=1

make sure all the db values are what you want them to be, cause it matters
for example: --db-name=magento2 should be the same name of the new table you just created in phpadmin

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.