Domanda

Il mio negozio ha circa 1000 prodotti e 600 fasci, con vista circa 8 negozi. Ciò equivale a circa 12.800 prodotti o giù di lì.

Stiamo per essere l'introduzione di elementi configurabili e uno degli attributi chiave che vogliamo riutilizzo è una selezione multipla campo modulo. Ogni prodotto ha un solo tipo selezionato, in modo che l'EAV backend tipo di dati che è stato configurato durante la messa a punto del negozio originale è stato scelto in modo non corretto. A questo punto vorremmo a migrare questo per il tipo di dati a discesa.

Esiste un metodo relativamente indolore per ottenere questo set up al di fuori della creazione di un attributo del tutto nuovo, porting i dati, ed eliminando il vecchio attr? Chiunque con qualsiasi esperienza facendo questo che mi può dare qualche consiglio utile?

È stato utile?

Soluzione

Non è solo necessario cambiare il backend_type nella tabella eav_attribute, ma anche di copiare i file dalla sorgente alla tabella di destinazione. Codice seguente vi aiuterà a realizzare questo:

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

Altri suggerimenti

Questa è vagamente basato sulla risposta da Tobias Zander, ma è un po 'più robusta e prudente circa l'aggiornamento in modo che è più sicuro per l'esecuzione su un ambiente di produzione. E 'anche costruita esplicitamente per spostare un multiselect ad un select, (discesa).

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

Ho aggiornato il codice di Tyler V. essere utilizzato direttamente nel database e per Magento 2.2.7. Il più grande cambiamento è che entity_type_id non viene utilizzato nelle tabelle del database corrente.

Ho anche creato il nuovo attributo eccellente manualmente tramite l'amministratore cruscotto Magento. Ho chiamato lo stesso di quello vecchio, ma accodati "nuovo" fino alla fine. Io eliminare il vecchio attributo di selezione multipla alla fine, quando ho finito e rinominare la nuova discesa uno al vecchio di un nome.

Per creare il nuovo attributo eccellente, accedi al tuo Admin Dashboard e fare clic su Stores> Attributi> Prodotti. Aggiungi nuovo attributo. Assicurarsi Scope è globale e il catalogo italiano Tipo di ingresso è a discesa. Poi vai a Negozi> Attributi> attributo impostato e trascinare il nuovo attributo sopra al vostro set di attributi.

Il mio vecchio multiselect attribute_id è 144. La mia nuova attribute_id discesa è 278. Sarà necessario cambiare questi per i numeri di identificazione appropriate.

  1. Verificare che i vecchi valori MultiSelect che hanno più di un valore (deve essere uno-a-uno per la discesa). O cambiare questi per avere un nuovo delimitatore diverso da una virgola in modo che possano rimanere come i loro nuovi valori o dividerli in singoli valori.

SELECT * FROM WHERE catalog_product_entity_varchar attribute_id = 144 e il valore LIKE '%,%'

  1. I valori VARCHAR Copiare tabella int, ignorando i valori vuoti e valori multipli.

INSERT INTO catalog_product_entity_int (attribute_id, store_id, entity_id, value) SELEZIONE '278' come attribute_id, store_id, entity_id, CONVERT (value, intero senza segno) come value DA catalog_product_entity_varchar DOVE attribute_id = 144 e il valore non è nullo e il valore! = '' E il valore NOT LIKE '%,%'

  1. Cambia attribute_id dal vecchio al nuovo nella tabella eav_attribute_option.

UPDATE eav_attribute_option SET attribute_id = 278 WHERE attribute_id = 144

  1. Reindicizza (da CLI: php bin / Magento indicizzatore: Reindicizza) e Cancella cache (da CLI: php bin / Magento cache: pulito). Poi vai a Negozi> Attributi> Prodotti e clicca sul tuo nuovo attributo. Assicurarsi che i vecchi valori ora stanno rivelando nel nuovo attributo.

  2. Elimina il vecchio attributo di selezione multipla e rinominare il nuovo al vecchio di un nome.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top