Dawno nic nie pisałam o naszych Magentach, ale ostatnio dłubałam troszkę przy upgradzie i napotkałam problem, który troszkę nerwów mi napsuł. Rzecz dotyczy błędu braku tabel catalog_category_product_index_replica
i catalog_category_product_index_store1
.
Całość problemu dotyczy tego, że tabela catalog_category_product_index_store1
tworzy się podczas reindexacji (Magento v. 2.2.10
) poleceniem:
php bin/magento indexer:reindex catalog_category_product
Natomiast tabela catalog_category_product_index_replica
dodana została w UpgradeSchema.php
modułu Magento_Catalog
w wersji 2.2.0
.
Mało tego, aby poprawnie wykonała się reindexacja, musimy mieć jeszcze w bazie dwie inne tabele (catalog_category_product_index
i catalog_category_product_index_tmp
). Magento tworzy je za pomocą pliku InstallSchema
, czyli w momencie instalacji modułu.
No i mamy tutaj inpas, ponieważ aby wykonać polecenie:
php bin/magento setup:upgrade
potrzebujemy tabeli catalog_category_product_index_store1
, w przeciwnym razie otrzymujemy błąd:
Module 'Magento_Catalog':
Upgrading schema.. SQLSTATE[42S02]: Base table or view not found: 1146 Table 'magento.catalog_category_product_index_store1' doesn't exist, query was: CREATE TABLE IF NOT EXISTS `catalog_category_product_index_replica` LIKE `catalog_category_product_index_store1
Natomiast, gdy próbujemy wykonać reindex:
php bin/magento indexer:reindex catalog_category_product
otrzymujemy błąd:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'magento.catalog_category_product_index_replica' doesn't exist, query was: DESCRIBE `catalog_category_product_index_replica`
Rozwiązać to możemy na dwa sposoby, stworzyć PATCH albo ręcznie dodać tabelę do bazy.
Wykorzystanie PATCH’a
Aby móc zaaplikować PATCH’a do naszego Magento, możemy użyć narzędzia composer-patches, lub też skorzystać z możliwości samego composera. Poniższą instrukcje należy dodać do pliku composer.json
:
{ "scripts": { "post-install-cmd": "patch -p0 < path/to/your.patch" } }
Poniżej znajduje się plik Patcha:
--- vendor/magento/module-catalog/Setup/UpgradeSchema.php 2019-11-12 16:43:39.884234228 +0100 +++ vendor/magento/module-catalog/Setup/UpgradeSchema.php 2019-11-12 16:00:03.338854758 +0100 @@ -37,6 +37,7 @@ $this->addUniqueKeyToCategoryProductTable($setup); } if (version_compare($context->getVersion(), '2.1.4', '<')) { + $this->addCatalogCategoryProductIndex($setup); $this->addSourceEntityIdToProductEavIndex($setup); } if (version_compare($context->getVersion(), '2.1.5', '<')) { @@ -841,4 +842,139 @@ $setup->getIdxName('catalog_product_index_price_tmp', ['min_price']) ); } + + /** + * @param SchemaSetupInterface $setup + */ + private function addCatalogCategoryProductIndex(SchemaSetupInterface $setup) + { + /** + * Create table 'catalog_category_product_index' + */ + $table = $setup->getConnection() + ->newTable($setup->getTable('catalog_category_product_index')) + ->addColumn( + 'category_id', + MagentoFrameworkDBDdlTable::TYPE_INTEGER, + null, + ['unsigned' => true, 'nullable' => false, 'primary' => true, 'default' => '0'], + 'Category ID' + ) + ->addColumn( + 'product_id', + MagentoFrameworkDBDdlTable::TYPE_INTEGER, + null, + ['unsigned' => true, 'nullable' => false, 'primary' => true, 'default' => '0'], + 'Product ID' + ) + ->addColumn( + 'position', + MagentoFrameworkDBDdlTable::TYPE_INTEGER, + null, + ['unsigned' => false, 'nullable' => true, 'default' => null], + 'Position' + ) + ->addColumn( + 'is_parent', + MagentoFrameworkDBDdlTable::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false, 'default' => '0'], + 'Is Parent' + ) + ->addColumn( + 'store_id', + MagentoFrameworkDBDdlTable::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false, 'primary' => true, 'default' => '0'], + 'Store ID' + ) + ->addColumn( + 'visibility', + MagentoFrameworkDBDdlTable::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false], + 'Visibility' + ) + ->addIndex( + $setup->getIdxName( + 'catalog_category_product_index', + ['product_id', 'store_id', 'category_id', 'visibility'] + ), + ['product_id', 'store_id', 'category_id', 'visibility'] + ) + ->addIndex( + $setup->getIdxName( + 'catalog_category_product_index', + ['store_id', 'category_id', 'visibility', 'is_parent', 'position'] + ), + ['store_id', 'category_id', 'visibility', 'is_parent', 'position'] + ) + ->setComment('Catalog Category Product Index'); + $setup->getConnection()->createTable($table); + + /** + * Create table 'catalog_category_product_index_tmp' + */ + $table = $setup->getConnection() + ->newTable( + $setup->getTable('catalog_category_product_index_tmp') + ) + ->addColumn( + 'category_id', + MagentoFrameworkDBDdlTable::TYPE_INTEGER, + null, + ['unsigned' => true, 'nullable' => false, 'default' => '0'], + 'Category ID' + ) + ->addColumn( + 'product_id', + MagentoFrameworkDBDdlTable::TYPE_INTEGER, + null, + ['unsigned' => true, 'nullable' => false, 'default' => '0'], + 'Product ID' + ) + ->addColumn( + 'position', + MagentoFrameworkDBDdlTable::TYPE_INTEGER, + null, + ['nullable' => false, 'default' => '0'], + 'Position' + ) + ->addColumn( + 'is_parent', + MagentoFrameworkDBDdlTable::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false, 'default' => '0'], + 'Is Parent' + ) + ->addColumn( + 'store_id', + MagentoFrameworkDBDdlTable::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false, 'default' => '0'], + 'Store ID' + ) + ->addColumn( + 'visibility', + MagentoFrameworkDBDdlTable::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false], + 'Visibility' + ) + ->addIndex( + $setup->getIdxName('catalog_category_product_index_tmp', ['product_id', 'category_id', 'store_id']), + ['product_id', 'category_id', 'store_id'] + ) + ->setOption( + 'type', + MagentoFrameworkDBAdapterPdoMysql::ENGINE_MEMORY + ) + ->setComment( + 'Catalog Category Product Indexer Temp Table' + ); + $setup->getConnection() + ->createTable($table); + + $setup->endSetup(); + } }
Zostanie on zaaplikowany po wykonaniu polecenia:
composer install
Po poprawnym zaaplikowaniu patcha polecenie php bin/magento setup:upgrade
nie powinno zrzucać już błędów.
Ręczne tworzenie tabel
Alternatywą dla wykorzystania Patch’a jest ręczne stworzenie tabel. Poniżej znajduje się create schema:
CREATE TABLE `catalog_category_product_index` ( `category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Category ID', `product_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Product ID', `position` int(11) DEFAULT NULL COMMENT 'Position', `is_parent` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Is Parent', `store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID', `visibility` smallint(5) unsigned NOT NULL COMMENT 'Visibility', PRIMARY KEY (`category_id`,`product_id`,`store_id`), KEY `CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY` (`product_id`,`store_id`,`category_id`,`visibility`), KEY `CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION` (`store_id`,`category_id`,`visibility`,`is_parent`,`position`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Catalog Category Product Index'; CREATE TABLE `catalog_category_product_index_tmp` ( `category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Category ID', `product_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Product ID', `position` int(11) NOT NULL DEFAULT '0' COMMENT 'Position', `is_parent` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Is Parent', `store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID', `visibility` smallint(5) unsigned NOT NULL COMMENT 'Visibility', PRIMARY KEY (`category_id`,`product_id`,`store_id`) ) ENGINE=MEMORY DEFAULT CHARSET=utf8 COMMENT='Catalog Category Product Indexer temporary table';
Należy zaznaczyć, że nie jest to ładne rozwiązanie i może stwarzać same problemy w przypadku wieloosobowego zespołu, podczas stawiania środowiska pracy. Także nie jest to rekomendowana przeze mnie metoda. Warto jednak wiedzieć jak można zrobić to ręcznie aby chociażby sprawdzić czy dodanie tych tabel wyeliminuje nasz podstawowy problem.