Frage

Mein Geschäft verfügt über rund 1000 Produkte und 600 Bündel mit ungefähr 8 Store -Aussichten. Dies entspricht ungefähr 12.800 Produkten oder so.

Wir werden Konfigurierungen einführen und eines der wichtigsten Attribute, die wir wiederverwenden möchten, ist ein Feld mit mehreren Selekten. Jedes Produkt hat nur einen Typ ausgewählt, sodass der EAV-Backend-Datentyp, der während der Einrichtung des ursprünglichen Speichers konfiguriert wurde, falsch ausgewählt wurde. Zu diesem Zeitpunkt möchten wir dies auf den Dropdown -Datentyp migrieren.

Gibt es eine relativ schmerzfreie Methode, um diese Ausrichtung außerhalb der Erstellung eines völlig neuen Attributs, des Ports der Daten und des Löschens des alten Attrils zu erstellen? Jemand mit Erfahrungen, die mir diese machen, die mir hilfreiche Ratschläge geben können?

War es hilfreich?

Lösung

Sie müssen nicht nur den Backend_Type in der Tabelle EAV_ATTRIBUTE ändern, sondern auch die Zeilen von der Quelle zu Zieltabelle kopieren. Der folgende Code hilft Ihnen dabei, dies zu erreichen:

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

Andere Tipps

Dies basiert locker auf der Antwort von Tobias Zander, ist jedoch etwas robuster und vorsichtiger in Bezug auf das Update, so dass es sicherer ist, in einer Produktionsumgebung zu leiten. Es ist auch ausdrücklich gebaut, um a zu bewegen multiselect zu einem select, (Dropdown-Liste.)

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

Ich habe den Code von Tyler V. aktualisiert, um direkt in der Datenbank und für Magento 2.2.7 verwendet zu werden. Die größte Änderung ist, dass entity_type_id in den aktuellen Datenbanktabellen nicht verwendet wird.

Ich habe das neue Superattribut auch manuell über das Magento Admin -Dashboard erstellt. Ich habe es genauso genannt wie das alte, aber bis zum Ende "neu" angehängt. Ich werde das alte Multiselect -Attribut am Ende löschen, wenn ich fertig ist, und den neuen Dropdown -Wert in den Namen des alten Namens umbenennen.

Um das neue Superattribut zu erstellen, melden Sie sich bei Ihrem Admin -Dashboard an und klicken Sie auf Speicher> Attribute> Produkte. Neues Attribut hinzufügen. Stellen Sie sicher, dass der Umfang global und der Catolog -Eingangstyp Dropdown ist. Gehen Sie dann zu Stores> Attributen> Attributsatz und ziehen Sie das neue Attribut in Ihr Attributsatz.

Mein alter Multiselect -Attribute_ID ist 144. Mein neuer Dropdown -Attribute_ID ist 278. Sie müssen diese in Ihre entsprechenden ID -Nummern ändern.

  1. Überprüfen Sie, ob die alten Multiselect-Werte, die mehr als einen Wert haben (für den Dropdown-Bereich eins zu eins sein müssen). Ändern Sie diese, um diese zu einem anderen Neutrainator als einem Komma zu haben, damit sie als eigene neue Werte bleiben oder sie in individuelle Werte aufteilen können.

Wählen Sie * aus catalog_product_entity_varchar wobei Attribute_id = 144 und Wert wie '%,%'

  1. Kopieren Sie die Varchar -Werte in die Int -Tabelle und ignorieren leere Werte und mehrere Werte.

In Catalog_Product_entity_int einfügen (in Catalog_Product_entity_int (attribute_id, store_id, entity_id, value) Wählen Sie '278' als attribute_id, store_id, entity_id, KONVERTIEREN(value, Nicht signierte Ganzzahl) als valueAus catalog_product_entity_varchar wobei Attribute_id = 144 und Wert nicht null und value! = '' Und Wert nicht wie '%,%' sind

  1. Ändern Sie Attribute_ID von alt nach neu in der Tabelle EAV_ATTRIBUTE_OPTION.

Aktualisieren Sie EAV_ATTRIBUTE_OPTION SET STRECTURE_ID = 278 WO DER STRECTUTE_ID = 144

  1. Reindedex (aus CLI: Php bin/Magento Indexer: Reindedex) und Clear Cache (aus CLI: PHP bin/Magento Cache: sauber). Gehen Sie dann zu Stores> Attribute> Produkte und klicken Sie auf Ihr neues Attribut. Stellen Sie sicher, dass die alten Werte jetzt im neuen Attribut angezeigt werden.

  2. Löschen Sie das alte Multiselect -Attribut und benennen Sie das neue in den alten Namen um.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top