我的商店大约有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的答案而宽松的,但是对更新的态度更加健壮和谨慎,因此在生产环境上运行更安全。它也是明确构建的 multiselectselect, , (落下。)

<?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号。

  1. 检查是否具有多个值的旧多选择值(必须是下拉列表的一对一)。要么将它们更改为具有逗号以外的新定界符,因此它们可以作为自己的新价值观保留,或者将其分为单个价值观。

选择 *来自catalog_product_entity_varchar,其中attribute_id = 144,值类似于'%,%'

  1. 将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!=''',值不像'%,%'

  1. 将attribute_id从旧到eav_attribute_option表中的旧更改。

更新eav_attribute_option set attribute_id = 278 werty attribute_id = 144

  1. ReIndex(来自CLI:PHP bin/magento索引器:Reindex)和清除缓存(来自CLI:PHP bin/magento Cache:Clean)。然后转到商店>属性>产品,然后单击您的新属性。确保现在在新属性中显示旧值。

  2. 删除旧的多选择属性,然后将新的属性重命名为旧的名称。

许可以下: CC-BY-SA归因
scroll top