Jump to content

No asigna "nleft" y "nright" al crear una categoría


yera

Recommended Posts

Les pongo en contexto, tengo prestashop 1.5.3.1.

 

Prestashop tiene una forma de jerarquizar las categorías en árbol y establece su posición en su "rama" con los campos "nleft" y "nright", no se que ha sucedido pero cada vez que creo una nueva categoría rellena esos campos con 0, por lo tanto la categoría aparece como creada, pero no es accesible por el browser:

 

www.dominio.es/id-nombreCategoria 

 

el resultado es un error 404.

 

la conclusión es:

 

Alguien sabe como restaurar esta metodología de Prestashop o donde genera estos valores a nivel de código para ver si puedo reajustarlos.

 

He modificado yo mismo los nleft y nright desde el phpMyAdmin y funcionan las categorías, la cuestión es que tendría que hacerlo manualmente cada vez que cree una nueva.

 

Enlace de interés: http://en.wikipedia.org/wiki/Nested_set_model

 

Gracias por todo, un saludo.

 

Link to comment
Share on other sites

  • 5 months later...

Hola, tengo el mismo error. ¿Conseguiste ver porqué motivo no completaba los campos nleft y nright al crear una categoría?

 

En caso de que tenga que rellenarlo a mano, ¿qué valores se meten en estos campos?

 

Muchas gracias de antemano, 

 

Saludos

Link to comment
Share on other sites

Hola, tengo el mismo error. ¿Conseguiste ver porqué motivo no completaba los campos nleft y nright al crear una categoría?

 

En caso de que tenga que rellenarlo a mano, ¿qué valores se meten en estos campos?

 

Muchas gracias de antemano, 

 

Saludos

 

Quizas esto: http://www.prestashop.com/forums/topic/93231-ps-v14-category-table-what-is-nleft-et-nright-for sirva..

Link to comment
Share on other sites

Gracias por tu respuesta.

 

He probado el módulo que dicen en ese hilo para regenerar el árbol de las categorías. En mi versión (1.6.0.9) el módulo se instala correctamente y cuando le doy a "regenerar" sale un mensaje diciendo que se ha hecho bien, pero no hace nada.

 

Por lo que lo he hecho manualmente:

 

Para todas las categorías :

- nleft debe ser superior al nleft de la categoría padre

- nright debe ser inferior al nright

 

No es la forma más adecuada, pero funciona. Aunque no me gusta tener que estar siempre haciendo esto manualmente, tocando en la base de datos... pero en fin.

Link to comment
Share on other sites

  • 1 month later...

Hola, 

Acabo de realizar el código para generarlo automáticamente por sql.

He hecho unas modificaciones sobre un código de joomla para mossets trees y adaptarlo para prestashop.
Código para Joomla:
http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28291301.html

 

Espero os sirva, cualquier cosa me pregutnais sin problemas, aunque el codigo a mi me funciona a la perfección.


Saludos
 

BEGIN

    DECLARE currentId, currentParentId  CHAR(36);
    DECLARE currentLeft                 INT;
    DECLARE startId                     INT DEFAULT 1;

    # Determines the max size for MEMORY tables.
    SET max_heap_table_size = 1024 * 1024 * 512;


    START TRANSACTION;
    # Temporary MEMORY table to do all the heavy lifting in,
    # otherwise performance is simply abysmal.
DROP TABLE IF EXISTS ps_category_tmp;
    CREATE TABLE `ps_category_tmp` (
        `id_category`        char(36) NOT NULL DEFAULT '',
        `id_parent` char(36)          DEFAULT NULL,
        `nleft`       int(11)  unsigned DEFAULT NULL,
        `nright`      int(11)  unsigned DEFAULT NULL,
        PRIMARY KEY      (`id_category`),
        INDEX USING HASH (`id_parent`),
        INDEX USING HASH (`nleft`),
        INDEX USING HASH (`nright`)
    ) ENGINE = MEMORY
    -- SELECT `id_category`, `id_parent`, `nleft`, `nright`  FROM   `health4_mt_cats`;
	select id_category, id_parent, nleft, nright from ps_category  ;


    # Leveling the playing field.
    UPDATE  `ps_category_tmp`
    SET     `nleft`  = NULL,
            `nright` = NULL;

    # Establishing starting numbers for all root elements.
    WHILE EXISTS (SELECT * FROM `ps_category_tmp` WHERE `id_parent` = 0 AND `nleft` IS NULL AND `nright` IS NULL LIMIT 1) DO

        UPDATE `ps_category_tmp`
        SET    `nleft`  = startId,
               `nright` = startId + 1
        WHERE  `id_parent`   = 0
          AND  `nleft`       IS NULL
          AND  `nright`      IS NULL
        LIMIT  1;

        SET startId = startId + 2;

    END WHILE;

    # Switching the indexes for the nleft/nright columns to B-Trees to speed up the next section, which uses range queries.
    DROP INDEX `nleft`  ON `ps_category_tmp`;
    DROP INDEX `nright` ON `ps_category_tmp`;
    CREATE INDEX `nleft`  USING BTREE ON `ps_category_tmp` (`nleft`);
    CREATE INDEX `nright` USING BTREE ON `ps_category_tmp` (`nright`);

    # Numbering all child elements
    WHILE EXISTS (SELECT * FROM `ps_category_tmp` WHERE `nleft` IS NULL LIMIT 1) DO
			
        # Picking an unprocessed element which has a processed parent.
        SELECT     `ps_category_tmp`.`id_category`
          INTO     currentId
        FROM       `ps_category_tmp`
        INNER JOIN `ps_category_tmp` AS `parents`
                ON `ps_category_tmp`.`id_parent` = `parents`.`id_category`
   WHERE      `ps_category_tmp`.`nleft` IS NULL
          AND      `parents`.`nleft`  IS NOT NULL
        LIMIT      1;

        # Finding the element's parent.
        SELECT  `id_parent`
          INTO  currentParentId
        FROM    `ps_category_tmp`
        WHERE   `id_category` = currentId;

        # Finding the parent's nleft value.
        SELECT  `nleft`
          INTO  currentLeft
        FROM    `ps_category_tmp`
        WHERE   `id_category` = currentParentId;

        # Shifting all elements to the right of the current element 2 to the right.
        UPDATE `ps_category_tmp`
        SET    `nright` = `nright` + 2
        WHERE  `nright` > currentLeft;

        UPDATE `ps_category_tmp`
        SET    `nleft` = `nleft` + 2
        WHERE  `nleft` > currentLeft;

        # Setting nleft and nright values for current element.
        UPDATE `ps_category_tmp`
        SET    `nleft`  = currentLeft + 1,
               `nright` = currentLeft + 2
        WHERE  `id_category`   = currentId;

    END WHILE;

   UPDATE `ps_category`, `ps_category_tmp`
    SET    `ps_category`.`nleft`  = `ps_category_tmp`.`nleft`,
           `ps_category`.`nright` = `ps_category_tmp`.`nright`
    WHERE  `ps_category`.`id_category`   = `ps_category_tmp`.`id_category`;

    COMMIT;



END
Edited by nadie
Moderación del foro edita el mensaje: Quitado enlace de publicidad | Firma debe ir en la firma (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

 

Hola, 

 

Acabo de realizar el código para generarlo automáticamente por sql.

He hecho unas modificaciones sobre un código de joomla para mossets trees y adaptarlo para prestashop.

Código para Joomla:

http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28291301.html

 

Espero os sirva, cualquier cosa me pregutnais sin problemas, aunque el codigo a mi me funciona a la perfección.

 

 

Saludos

www.prestashopconector.com

 

BEGIN

    DECLARE currentId, currentParentId  CHAR(36);
    DECLARE currentLeft                 INT;
    DECLARE startId                     INT DEFAULT 1;

    # Determines the max size for MEMORY tables.
    SET max_heap_table_size = 1024 * 1024 * 512;


    START TRANSACTION;
    # Temporary MEMORY table to do all the heavy lifting in,
    # otherwise performance is simply abysmal.
DROP TABLE IF EXISTS ps_category_tmp;
    CREATE TABLE `ps_category_tmp` (
        `id_category`        char(36) NOT NULL DEFAULT '',
        `id_parent` char(36)          DEFAULT NULL,
        `nleft`       int(11)  unsigned DEFAULT NULL,
        `nright`      int(11)  unsigned DEFAULT NULL,
        PRIMARY KEY      (`id_category`),
        INDEX USING HASH (`id_parent`),
        INDEX USING HASH (`nleft`),
        INDEX USING HASH (`nright`)
    ) ENGINE = MEMORY
    -- SELECT `id_category`, `id_parent`, `nleft`, `nright`  FROM   `health4_mt_cats`;
	select id_category, id_parent, nleft, nright from ps_category  ;


    # Leveling the playing field.
    UPDATE  `ps_category_tmp`
    SET     `nleft`  = NULL,
            `nright` = NULL;

    # Establishing starting numbers for all root elements.
    WHILE EXISTS (SELECT * FROM `ps_category_tmp` WHERE `id_parent` = 0 AND `nleft` IS NULL AND `nright` IS NULL LIMIT 1) DO

        UPDATE `ps_category_tmp`
        SET    `nleft`  = startId,
               `nright` = startId + 1
        WHERE  `id_parent`   = 0
          AND  `nleft`       IS NULL
          AND  `nright`      IS NULL
        LIMIT  1;

        SET startId = startId + 2;

    END WHILE;

    # Switching the indexes for the nleft/nright columns to B-Trees to speed up the next section, which uses range queries.
    DROP INDEX `nleft`  ON `ps_category_tmp`;
    DROP INDEX `nright` ON `ps_category_tmp`;
    CREATE INDEX `nleft`  USING BTREE ON `ps_category_tmp` (`nleft`);
    CREATE INDEX `nright` USING BTREE ON `ps_category_tmp` (`nright`);

    # Numbering all child elements
    WHILE EXISTS (SELECT * FROM `ps_category_tmp` WHERE `nleft` IS NULL LIMIT 1) DO
			
        # Picking an unprocessed element which has a processed parent.
        SELECT     `ps_category_tmp`.`id_category`
          INTO     currentId
        FROM       `ps_category_tmp`
        INNER JOIN `ps_category_tmp` AS `parents`
                ON `ps_category_tmp`.`id_parent` = `parents`.`id_category`
   WHERE      `ps_category_tmp`.`nleft` IS NULL
          AND      `parents`.`nleft`  IS NOT NULL
        LIMIT      1;

        # Finding the element's parent.
        SELECT  `id_parent`
          INTO  currentParentId
        FROM    `ps_category_tmp`
        WHERE   `id_category` = currentId;

        # Finding the parent's nleft value.
        SELECT  `nleft`
          INTO  currentLeft
        FROM    `ps_category_tmp`
        WHERE   `id_category` = currentParentId;

        # Shifting all elements to the right of the current element 2 to the right.
        UPDATE `ps_category_tmp`
        SET    `nright` = `nright` + 2
        WHERE  `nright` > currentLeft;

        UPDATE `ps_category_tmp`
        SET    `nleft` = `nleft` + 2
        WHERE  `nleft` > currentLeft;

        # Setting nleft and nright values for current element.
        UPDATE `ps_category_tmp`
        SET    `nleft`  = currentLeft + 1,
               `nright` = currentLeft + 2
        WHERE  `id_category`   = currentId;

    END WHILE;

   UPDATE `ps_category`, `ps_category_tmp`
    SET    `ps_category`.`nleft`  = `ps_category_tmp`.`nleft`,
           `ps_category`.`nright` = `ps_category_tmp`.`nright`
    WHERE  `ps_category`.`id_category`   = `ps_category_tmp`.`id_category`;

    COMMIT;



END

Buenas chavales, tengo el mismo problema que todos y he probado el código del amigo PrestashopConector pero me da error de proxy cuando lo ejecuto como procedimiento en phpmyadmin, concretamente un error 502.

 

¿Hay alguien que lo haya probado con éxito? ¿O tenéis alguna forma de hacerlo diferente a la mía?

 

Llevo mucho tiempo con esto y ya no vale poner los nleft y nright a mano, son más de 500 categorías..

 

Gracias a tod@s.

Link to comment
Share on other sites

Hola Patuky

 

Estas recibiendo un error de "stack overflow". Habla con tu hosting para que te aumenten el tamaño de pila ya que no debes tener sufciente pila / memoria para ejecutar el proceso.

 

Si te fijas en el código verás que este proceso se realiza medienate la creación de una tabla temporal en donde se hacen las operaciones y despuúes volcado de esta infromación a la tabla category.

 

Además de crear el proceso, luego hay que ejecutarlo.

 

Saludos

Edited by nadie
Moderación del foro edita el mensaje: Quitado enlace de publicidad | Firma debe ir en la firma (see edit history)
Link to comment
Share on other sites

  • 1 month later...

a mi este código me da el siguiente error cuando lo pongo en SQL dentro del php my admin

consulta SQL: Documentación


SELECT * FROM `ps_category` WHERE 1BEGIN

    DECLARE currentId, currentParentId  CHAR(36);
MySQL ha dicho: Documentación

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE currentId, currentParentId  CHAR(36)' at line 3 
Link to comment
Share on other sites

Hola Voignar,

 

Estas haciendo un procecure ? En caso afrimativo deberías empezar con el BEGIN... 
En tu post hay además de un "1" pegado al BEGIN, UNA QUERY antes con el where statment sin terminar...

 

SELECT * FROM `ps_category` WHERE 1BEGIN

 

Esta sentencia no tiene sentido...

Recuerdo que para la ejecución de esta rutina hay que tener unos niveles mínimos de lenguaje sql y de su sintaxis para mysql... así como conocer el uso de procedures, funciones y scripts...

Si montas  el proceso desde begin y lo ejecutas no tendrías porque tener problemas en su ejecución.

 

Saludos y buena suerte

Link to comment
Share on other sites

Si, después lo hice de otra forma, lo estuve ejecutando como si fuera una consulta sin más, y no funcionaba, ya después vi lo de los procedures y ya entendí todo.

 

Ya después me ha dado un error de tiempo de ejecución que tengo que solucionar con mi hosting.

 

gracias por la respuesta

Link to comment
Share on other sites

  • 1 year later...

Buenas tardes,

 

El código a ejecutar es un procedimiento de mysql, si bien no hay que ser un dba experto, si que se tienen que tener ciertas nociones de sql y bases de datos para ejcutarlas como le paso al primer compañero que contesto a nuestra respuestas.

 

Si los parent childs están bien creados (evitando así que entre en bucle infinito el proceso), insertaís ese código en el eidtor de procedimientos almacenados y os lo ejecutará sin problemas.

 

Si lo hacéis desde una ventana de sql tendréis que poner el create procedure ComoSeLlame antes.

 

Una vez creado este proceso acordaros que hay q ejecutarlo, o bien  mediación de interface grafica con "ejecutar" o bien con sentencia sql call ComoSeLlame 

 

Si con esta información no se os ejecuta, googleear los errores e ir avanzando hasta que os funciones.

 

Repito, no hay que ser experto.. pero es un fragmento de código de programación sql y hay que saberlo crear y ejecutar. 

 

Saludos y mucha suerte con ello.

Link to comment
Share on other sites

  • 1 year later...

Hello Prestashopconector, I am face to this issue and trying to execute the procedure you indicated.

The procedure is executed, I can see tmp table being field up but there is an infinite loop: numbers in nleft and nright can't stop growing.

My category table contains 570 lines. It's a multishop prestashop.

What do I have to fix before executing this procedure in order to avoid the loop and getting success?

Gracias for your precious answer,

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...