Question

Mon magasin a environ 1000 produits et 600 faisceaux, avec vue sur environ 8 magasins. Cela équivaut à environ 12 800 produits environ.

Nous allons introduirons et l'une des caractéristiques de configuration des attributs clés que nous voulons réutiliser est un champ de formulaire multi-sélection. Chaque produit a un seul type choisi, de sorte que le backend de EAV données de type qui a été configuré au cours de la mise en place de la banque d'origine a été choisie de manière incorrecte. À ce stade, nous aimerions migrer ce le type de données menu déroulant.

Y at-il une méthode relativement indolore pour obtenir cet ensemble en dehors de la création d'un attribut entièrement nouveau, le portage des données, et la suppression de l'ancien attr? Toute personne ayant des expériences faisant cela qui peut me prêter quelques conseils utiles?

Était-ce utile?

La solution

Vous avez non seulement de changer le backend_type dans la table eav_attribute, mais aussi copier les lignes de la source à la table cible. code suivant vous aidera à y parvenir:

$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);

Autres conseils

Ceci est vaguement basé sur la réponse par Tobias Zander, mais est un peu plus robuste et prudent quant à la mise à jour de sorte qu'il est plus sûr de fonctionner sur un environnement de production. Il est également construit explicitement pour déplacer un multiselect à un select, (menu déroulant).

<?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();

J'ai mis à jour le code de Tyler V. pour être utilisé directement dans la base de données et pour Magento 2.2.7. Le plus grand changement est que entity_type_id n'est pas utilisé dans les tables de base de données actuelle.

J'ai aussi créé le nouvel attribut super manuellement via le tableau de bord d'administration Magento. Je l'ai appelé le même que l'ancien à la fin, mais apposé « nouveau ». Je supprimerai l'ancien attribut multiselect à la fin quand j'ai fini et renommer le nouveau déroulant au nom de l'ancien.

Pour créer le nouvel attribut super, connectez-vous à votre administrateur Dashboard et cliquez sur Boutiques> Attributs> Produits. Ajouter un nouvel attribut. Assurez-vous que Scope est global et le type d'entrée Vitrier est Dropdown. Ensuite, allez aux magasins> Attributs> ensemble d'attributs et faites glisser le nouvel attribut sur votre jeu d'attributs.

Mon ancien attribute_id de MultiSelect 144. Mon nouveau attribute_id déroulant est 278. Vous devrez changer ces à vos numéros d'identification appropriés.

  1. Vérifiez si les anciennes valeurs de MultiSelect qui ont plus d'une valeur (doit être l'un à l'autre pour le menu déroulant). Modifiez ces d'avoir un nouveau délimiteur autre qu'une virgule afin qu'ils puissent rester aussi leurs propres nouvelles valeurs ou les diviser en valeurs individuelles.

SELECT * FROM catalog_product_entity_varchar OÙ attribute_id = 144 ET LIKE '%,%'

  1. Copier les valeurs varchar à la table int, en ignorant les valeurs et les valeurs multiples vides.

INSERT INTO catalog_product_entity_int (attribute_id, store_id, entity_id, value) SELECT '278' comme attribute_id, store_id, entity_id, CONVERT (value, Entier non signé) comme value DE catalog_product_entity_varchar OÙ attribute_id = 144 et la valeur IS NOT NULL et la valeur! = '' Et la valeur NOT LIKE '%,%'

  1. Changement attribute_id de l'ancien au nouveau tableau de eav_attribute_option.

UPDATE eav_attribute_option SET attribute_id = 278 OÙ attribute_id = 144

  1. Réindexer (CLI de: bin php / magento indexeur: réindexation) et Vider le cache (de CLI: bin php / magento cache: propre). Ensuite, allez aux magasins> Attributs> Produits et cliquez sur votre nouvel attribut. Assurez-vous que les anciennes valeurs ne sont maintenant dans le nouvel attribut.

  2. Supprimer l'ancien attribut multiselect et renommer le nouveau au nom de l'ancien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top