Як я можу виправити "Елемент (Mage_Catalog_Model_Product) з тим самим ідентифікатором" xxx "вже існує"?


18

Я отримував цю помилку при спробі фільтрувати колекцію продуктів

Item (Mage_Catalog_Model_Product) with the same id "6058" already exist і хотів запитати, що може спричинити помилку, оскільки всередині Magento є лише один (видимий) продукт із таким самим ідентифікатором.

Чи є таблиця, яку потрібно очистити, щоб видалити цей дублікат?


Чи можете ви додати якийсь код? Вам потрібно використовувати group byлише унікальний ідентифікатор продукту. Дивіться magento.stackexchange.com/questions/12773/…
Ренон Стюарт

@RS, Привіт, я все ще намагаюся знайти причину, яку я опублікую назад, як тільки я
відвідаю

Відповіді:


36

Додавання distinctзапропонованого до прийнятої відповіді вирішує проблему, але у неї є проблеми з продуктивністю. База даних може створювати тимчасові таблиці на диску при виконанні запиту, distinctі це сповільнить ваш запит. Ви можете замість цього додати groupумову до колекції для видалення дублікатів.

Погляньте на цю публікацію . Те, що вони зробили (і я це теж зробив), групується за ідентифікатором сутності. Це має працювати краще.

//adding filters to the collection..

$collection->getSelect()
           ->group('e.entity_id');

скажіть, будь ласка, куди нам потрібно додати цей код
Baby in Magento

@BabyinMagento, де б ви не використовували свою колекцію у своєму власному коді. Ця помилка виникає під час створення користувацьких модулів, які отримують колекції з бази даних. Це означає, що він може з’явитися, якщо ви нещодавно встановили модулі сторонніх розробників. У такому випадку розташування помилки залежить від розробника згаданого модуля.
Вік

Це distinct()рішення дозволить видалити будь-які додаткові записи із запиту, а це означає, що ви можете втратити дані, не помічаючи. Тож це може бути не найкращим рішенням, як у моєму випадку. Зараз я намагаюся знайти спосіб отримати обидва записи з моєї об'єднаної таблиці в колекцію, щоб я міг показати обидва записи в одному рядку в сітці.
Жак

Маленька примітка: його важливо не пов’язати це з колекцією, але найперше поставити ваш збір на змінну і, ніж зробити $ collection-> getSelect () -> group ('e.entity_id');
Рікерт

де я можу оновити цей код?
zus

7

Зазвичай це помилка в даних або в реалізації колекції.

Ось вирішення більш широкого питання. Це працює на довільному зборі, не тільки дляCatalog_Model_Product .

Крок 1. Змінити файл ядра lib/Varien/Data/Collection.php, function addItem(), але в відміну від цієї відповіді , не приховуйте помилку.

Натомість додайте додаткову інформацію про помилки до викинутого винятку:

        if (isset($this->_items[$itemId])) {
            throw new Exception('Item ('.get_class($item).
                ') with the same id "'.$item->getId().'" already exist' .
                '. SQL that caused this: ' . $this->getSelect());
        }

Крок 2. Візьміть запит про порушення від свого звіту про помилки та запустіть його вручну. Подивіться, які записи копіюють ключ збору. Додайтеorder by <key field> за потребою.

Розділіть запит на видалення таблиць-учасниць, що беруть участь один за одним, і подивіться, який запис викликав дублювання.

Я вважаю, цей патч повинен бути в основі.


3

Ваша проблема полягає в тому, що у вас є колекція (швидше за все, з приєднанням або об'єднанням), яка призводить до того, що один і той же продукт завантажується в колекцію двічі.

Ви можете змінити завантажену колекцію, додавши в обраний об'єкт чіткий метод.

Дивіться http://framework.zend.com/manual/1.12/en/zend.db.select.html

$db->select()
         ->distinct()

Але це пов'язано з властивими проблемами. Використання чітко спричинить створення тимчасових таблиць на диску, а не в пам'яті, що спричиняє штрафи за продуктивність.


0

У моєму випадку

->getSelect()->group('e.entity_id');

я не працюю:

->getSelect()->group('main_table.entity_id');

Мат також бути пристрасним для когось

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.