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
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
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.
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.
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);
}
}
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.
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);
Magento 2.3 developers will not add support for tinytext
data type. varchar
type is recommended to use instead of tinytext
.
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.
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/
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.
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