更改后端属性类型从多选择性转换为下拉
-
16-10-2019 - |
题
我的商店大约有1000种产品和600个捆绑包,大约有8个商店景观。这相当于大约12,800种产品左右。
我们将介绍配置物,我们要重复使用的关键属性之一是多选择式表单字段。每种产品仅选择一种类型,因此在原始商店设置期间配置的EAV后端数据类型被错误地选择。在这一点上,我们想将其迁移到下拉数据类型。
是否有任何相对无痛的方法可以在创建一个全新的属性,移植数据并删除旧attr之外进行设置?任何有经验的人都可以为我提供一些有用的建议吗?
解决方案
您不仅需要在eav_attribute表中更改后端_type,还必须将行从源表复制到目标表。以下代码将帮助您完成此操作:
$connection = _getConnection('core_write');
$attributeIds = 'yourattributeid';
$entityTypeId = 'oldentitytypeid;
$sql = 'SELECT * FROM catalog_product_entity_varchar WHERE attribute_id IN ('.$attributeIds.') AND entity_type_id = '.$entityTypeId;
$rows = $connection->fetchAll($sql);
foreach ($rows as $row){
$price = $row['value'];
if (!is_null($price)) {
$sql = 'INSERT INTO catalog_product_entity_decimal (`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`)
VALUES (?,?,?,?,?)';
$connection->query($sql, array($row['entity_type_id'], $row['attribute_id'], $row['store_id'], $row['entity_id'], $price));
}
$sql = 'DELETE FROM catalog_product_entity_varchar WHERE value_id = ?'; // or your old storage table
$connection->query($sql, $row['value_id']);
}
$sql = 'UPDATE eav_attribute SET backend_type="newbackendtype" WHERE attribute_id IN ('.$attributeIds.')';
$connection->query($sql);
其他提示
这是基于Tobias Zander的答案而宽松的,但是对更新的态度更加健壮和谨慎,因此在生产环境上运行更安全。它也是明确构建的 multiselect
到 select
, , (落下。)
<?php
$installer = $this;
$installer->startSetup();
$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$attributeCode = 'my_atribute';
/** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
$attribute = Mage::getModel('catalog/resource_eav_attribute') ->loadByCode(Mage_Catalog_Model_Product::ENTITY, $attributeCode);
$attributeId = $attribute->getId();
$entityTypeId = $setup->getEntityTypeId('catalog_product');
$connection = $setup->getConnection('core_write');
$ea = $setup->getTable('eav_attribute');
$cea = $setup->getTable('catalog_eav_attribute');
$cpei = $setup->getTable('catalog_product_entity_int');
$cpev = $attribute->getBackendTable(); //$setup->getTable('catalog_product_entity_varchar');
$ip = $setup->getTable('index_process');
/*
* Sanity check on the existing attribute
*/
if ($attribute->getFrontendInput() != 'multiselect' || $attribute->getBackendType() != 'varchar') {
Mage::throwException("Cannot migrate `{$attributeCode}`` because it is not the expected backend or frontend type.");
return;
}
$connection->query("LOCK TABLES {$cpev} WRITE");
/*
* Check that none of the entities in the database have multiple selected values
*/
$num = (int)$connection->fetchOne("
SELECT COUNT(*) as num
FROM {$cpev}
WHERE ". $connection->prepareSqlCondition('attribute_id', $attributeId) ."
AND ". $connection->prepareSqlCondition('entity_type_id', $entityTypeId) ."
AND value LIKE '%,%'
");
if ($num !== 0) {
$connection->query("UNLOCK TABLES");
Mage::throwException("Cannot migrate `{$attributeCode}`` because it contains {$num} entities with multiple selected values.");
return;
}
$connection->beginTransaction();
$connection->query("
INSERT INTO {$cpei}
(`entity_type_id`, `attribute_id`, `store_id`, `entity_id`, `value`)
SELECT `entity_type_id`, `attribute_id`, `store_id`, `entity_id`, CONVERT(`value`,UNSIGNED INTEGER) as `value`
FROM {$cpev}
WHERE ". $connection->prepareSqlCondition('attribute_id', $attributeId) ."
AND ". $connection->prepareSqlCondition('entity_type_id', $entityTypeId) ."
AND value IS NOT NULL
AND value != ''
");
$connection->query("
UPDATE {$ea}
SET
`frontend_input` = 'select', # from 'multiselect'
`backend_type` = 'int', # from 'varchar'
`backend_model` = NULL, # from 'eav/entity_attribute_backend_array'
`source_model` = 'eav/entity_attribute_source_table' # from NULL
WHERE ". $connection->prepareSqlCondition('attribute_id', $attributeId) ."
");
/*
* OPTIONAL: Migrate the new attribute to be a configurable attribute
*/
$connection->query("
UPDATE {$cea}
SET `is_configurable` = '1'
WHERE ". $connection->prepareSqlCondition('attribute_id', $attributeId) ."
");
$connection->query("UNLOCK TABLES");
$connection->query("
DELETE
FROM {$cpev}
WHERE ". $connection->prepareSqlCondition('attribute_id', $attributeId) ."
AND ". $connection->prepareSqlCondition('entity_type_id', $entityTypeId) ."
");
$connection->query("
UPDATE {$ip}
SET `status` = 'require_reindex'
WHERE `indexer_code` IN ('catalog_product_attribute', 'catalog_product_flat')
");
$connection->commit();
$installer->endSetup();
我已经更新了Tyler V.的代码,该代码将直接在数据库中和Magento 2.2.7中使用。最大的变化是当前数据库表中未使用Entity_Type_id。
我还通过Magento Admin仪表板手动创建了新的Super属性。我的名字与旧的命名相同,但在“新”结束时命名为“新”。当我完成并将新的下拉列表重命名为“旧One”的名称时,我将在末尾删除旧的多选择属性。
要创建新的超级属性,请登录管理仪表板,然后单击“商店”>“属性”>“产品”。添加新属性。确保范围是全局的,并且catolog oftolt类型是订单。然后转到商店>属性>属性集,然后将新属性拖动到您的属性集。
我旧的MultiSelect Attribute_id是144。我的新下拉列表attribute_id是278。您需要将其更改为适当的ID号。
- 检查是否具有多个值的旧多选择值(必须是下拉列表的一对一)。要么将它们更改为具有逗号以外的新定界符,因此它们可以作为自己的新价值观保留,或者将其分为单个价值观。
选择 *来自catalog_product_entity_varchar,其中attribute_id = 144,值类似于'%,%'
- 将VARCHAR值复制到INT表,忽略空值和多个值。
插入catalog_product_entity_int(attribute_id
, store_id
, entity_id
, value
)选择“ 278”为 attribute_id
, store_id
, entity_id
, 兑换(value
,未签名的整数) value
来自catalog_product_entity_varchar,其中attribute_id = 144,值不为null and value!=''',值不像'%,%'
- 将attribute_id从旧到eav_attribute_option表中的旧更改。
更新eav_attribute_option set attribute_id = 278 werty attribute_id = 144
ReIndex(来自CLI:PHP bin/magento索引器:Reindex)和清除缓存(来自CLI:PHP bin/magento Cache:Clean)。然后转到商店>属性>产品,然后单击您的新属性。确保现在在新属性中显示旧值。
删除旧的多选择属性,然后将新的属性重命名为旧的名称。