Como trabajar con la base de datos de PrestaShop
La mayoría de módulos y desarrollos en PrestaShop requieren que se use o ingrese información en la base de datos de la tienda.
PrestaShop dispone en su núcleo de la clase DB que es esencial para hacer consultas, inserciones, eliminación y alteraciones en la base de datos de la tienda.
Además de proporcionar abstracción potencial para otros tipos de bases de datos relacionales, la clase DB dispone de varias herramientas para hacer la vida más fácil.
En este artículo vas a conocer una de las mejores formas para ejecutar consultas en la base de datos de una tienda PrestaShop.
Crear nuevas tablas en la base de datos de una tienda PrestaShop
Muchos módulos o desarrollos específicos necesitan crear nuevas tablas en la base de datos de la tienda para guardar la información que manejan.
En el método install() de un módulo es habitual crear nuevas tablas. Una forma de hacerlo fácil sería, por ejemplo, así:
Db::getInstance()->Execute(
'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'item` (
`id_item` int(10) NOT NULL AUTO_INCREMENT ,
`name` varchar(128) NOT NULL ,
`description` text,
`active` int(2) unsigned NOT NULL,
`date_add` datetime NOT NULL,
`date_upd` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id_item`)
) ENGINE = InnoDB DEFAULT CHARSET=utf8;'
);
Este código ejecutado en un entorno PHP crea una tabla llamada «item» que contiene un identificador, un nombre, una descripción, un estado boleano, una fecha de creación y una fecha de actualización. El identificador es la clave primaria.
Alterar tablas existentes en la base de datos
En algunos casos, quizá la idea de tu módulo no es crear una tabla, sino, alterar un campo existente agregando algún valor. Lo puedes hacer así:
Db::getInstance()->Execute(
'ALTER TABLE '._DB_PREFIX_.'item ADD featured int(1) NOT NULL'
);
En este caso particular, estoy agregando un nuevo campo llamado «featured» que será un boleano en la tabla de elementos. Se podría utilizar para destacar elementos, por ejemplo.
Actualizar campos existentes en una tabla de la base de datos
Quizás lo que estás buscando es hacer una actualización de algún campo en alguna tabla ya existente en la base de datos. Esto lo puedes hacer así:
Db::getInstance()->Execute(
'UPDATE '._DB_PREFIX_.'item SET active=1 WHERE id_item = 8'
);
En el código anterior estoy actualizando el registro «active» estableciéndolo en 1 para el elemento con identificador 8.
Esta es una actualización con condición para que puedas ver algunas de las posibilidades que ofrece SQL.
Eliminar una tabla de la base de datos
En el proceso de desinstalación o dentro de la función unninstall() de un módulo es muy posible que estés interesado en saber como eliminar una tabla de la base de datos. En este caso, tan solo debes ejecutar algo como lo que sigue:
Db::getInstance()->Execute(
'DROP TABLE '._DB_PREFIX_.'item'
);
Esta llamada elimina la tabla «item» de la base de datos por completo y sin dejar rastro.
Eliminar registros de una tabla de la base de datos
Si quieres eliminar los registros manteniendo el índice puedes ejecutar:
Db::getInstance()->Execute(
'DELETE FROM '._DB_PREFIX_.'item'
);
Para eliminar un registro en concreto puedes hacer una eliminación condicionada como lo siguiente:
Db::getInstance()->Execute(
'DELETE FROM '._DB_PREFIX_.'item
WHERE id_item = 8'
);
Vaciar los datos de una tabla de la base de datos
Para vaciar los datos de una tabla y reiniciar los índices puedes hacer un Truncate:
Db::getInstance()->Execute(
'TRUNCATE TABLE '._DB_PREFIX_.'item'
);
Insertar datos en una tabla de la base de datos
De la misma forma, también se puede utilizar la función Execute() para insertar datos en una tabla de la base de datos. Fíjate en el siguiente ejemplo:
Db::getInstance()->Execute(
'INSERT INTO '._DB_PREFIX_.'item (id_item, name, active) VALUES ('.(int)$id_item.', "'.pSQL($name).'", 1)'
);
En este caso, estoy insertando unos datos dinámicos en la tabla «item».
Las variables $id_item y $name tiene que estar definidas y con datos válidos para que esta consulta funcione correctamente.
Consultar un campo de una tabla en la base de datos
Si por ejemplo quieres recuperar el nombre de un elemento de la base de datos directamente, puedes usar la función getValue():
$item_name = Db::getInstance()->getValue(
'SELECT name FROM '._DB_PREFIX_.'item
WHERE id_item = 8'
);
Consultar una fila de una tabla en la base de datos
Para recuperar todos los datos de un elemento en concreto puedes usar:
$item = Db::getInstance()->getRow(
'SELECT * FROM '._DB_PREFIX_.'item
WHERE id_item = 8'
);
echo $item['name'];
La función getRow() te retorna una fila de la tabla de la base de datos en formato array.
Consultar todos los elementso de una tabla en la base de datos
Para recuperar todos los elementos y sus datos puedes usar:
En este caso particular, estoy recuperando todos los elementos.
Si hay elementos, los itero con un foreach para imprimir el nombre de cada uno de ellos.
Otras consideraciones
La clase DB se compone de dos clases:
- Clase DB en el archivo ~/classes/Db.php es abstracta
- Clase MySQL en el archivo ~/classes/MySQL.php se basa en DB
A pesar de que DB es seudo único, aún se puede activar manualmente si es necesario cuando el desarrollador se encuentre público. Sin embargo, en PrestaShop debe ser accedido como sigue:
$db = Db::getInstance();
En algunos casos, podemos ver las peticiones según el siguiente código:
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);
Cuando el anterior está conectado, podría ingresar servidores esclavos si el usuario de PrestaShop permite el uso de servidores esclavos MySQL en su arquitectura.
El argumento estándar PS_USE_SQL_SLAVE sólo se debe utilizar para consultas sólo de lectura (SELECT, SHOW, etc.), y sólo si el resultado no necesita ser actualizado inmediatamente. Es necesario utilizar el servidor maestro para realizar una consulta de selección justo después de ingresar algo en la misma tabla.
El método autoExecute() genera automáticamente la inserción o actualización de la base desde una tabla de datos.
Este método debe utilizarse en lugar de hacer peticiones INSERT o UPDATE a menos que estas peticiones sean un poco más complejas (con funciones SQL, consultas intersecadas, etc.).
La ventaja de utilizar un método para realizar todo es que centraliza las peticiones.
Puedes editar este método utilizando el sistema de reemplazo de PrestaShop cuando existe un proceso en particular para aplicar a las tablas durante la inserción.
Db::getInstance()->autoExecute(
'item',
array(
'name' => pSQL($name),
'active' => 1
), 'INSERT'
);
Solicitar este método ofrece como resultado la siguiente consulta SQL:
INSERT INTO item (name) VALUES ('myName', 1)
Importante :
Asegúrate siempre de que tus datos están protegidos antes de transferirlos a autoExecute().
En el ejemplo, el identificador debe ser un entero y el nombre debe estar protegido contra inyecciones SQL con pSQL().
Con PrestaShop, los nombres de las tablas deben ir siempre precedidos por el prefijo, incluida la constante DB_PREFIX.
Puedes generar una consulta de actualización sustituyendo el tercer argumento con UPDATE.
En este caso, puedes eludir las restricciones SQL (por ejemplo: …->autoExecute('table', $data, 'UPDATE', 'myField = 13 AND id < 8'); ).
Existe una versión DELETE de autoExecute() que puede ser utilizado para el mismo propósito.
El argumento $limit limita el número de elementos guardados que puede eliminar.
La otra ventaja de este método es que puede ser utilizado con el sistema de caché de consulta de SQL de PrestaShop y elimina las consultas almacenadas en caché a menos que el argumento $use_cache argumento sea falso.
Db::getInstance()->delete('item', 'id_item < 15', 3);
En este caso, la siguiente consulta se genera:
DELETE FROM item WHERE id_item < 15 LIMIT 3
Como hemos podido observar al principio, el método execute() ejecuta la consulta SQL ofrecida.
Esta función sólo debe ser utilizada para consultas sólo de escritura (INSERT, UPDATE, DELETE, TRUNCATE etc.), ya que también elimina la consulta caché (a menos que el argumento $use_cache sea falso).
Por ejemplo:
$sql = 'DELETE FROM '._DB_PREFIX_.'item WHERE date_upd < NOW()';
if (!Db::getInstance()->Execute($sql)) {
die('Erreur etc.');
}
El método executeS() ejecuta la consulta SQL ofrecida y carga todos los resultados en una tabla multidimensional.
Este método solo se debe usar con consultas sólo de lectura (SELECT, SHOW etc.).
Los resultados de la consulta serán almacenados en caché a menos que el argumento $use_cache sea falso.
$sql = 'SELECT * FROM '._DB_PREFIX_.'item';
if ($results = Db::getInstance()->ExecuteS($sql)) {
foreach ($results as $row) {
echo $row['id_item'].' :: '.$row['name'].'<br />';
}
}
El método getRow() ejecuta la consulta SQL ofrecida y recoge la primera línea de resultados.
Este métdo sólo debe ser utilizado con consultas sólo de lectura (SELECT, SHOW, etc.).
Los resultados de la consulta se almacenan en caché a menos que el argumento $use_cache sea falso.
$sql = 'SELECT COUNT(*) FROM '._DB_PREFIX_.'item';
$total_items = Db::getInstance()->getValue($sql);
Otros métodos que pueden ser muy útiles:
- Insert_ID(): muestra el ID creado por la última consulta ejecutada INSERT.
- affected_Rows(): muestra el número de líneas afectadas por la última consulta ejecutada UPDATE o DELETE.
- getMsgError(): muestra el último mensaje de error si una consulta ha fracasado.
- getNumberError(): muestra el último número de error si una consulta ha fracasado.
Otro recurso muy interesante para ejecutar sentencias sql desde el PHP en PretaShop es utilizar la clase DbQuery. En el blog de Ivan Garcia lo explica muy bien.
Muchas Gracias por este excelente aporte! Siempre lo tengo a la mano cuando desarrollo.
Excelente amigo, esto me ha servido mucho para crear mi propios modulos. Muchas gracias
Buenos dias, creé un Módulo para el FrontEnd, el módulo me guarda en una BD los datos introducidos en el formulario pero ahora necesito que esos datos antes guardados se muestren en una nueva tabla (GRID) en el mismo formulario.
espero me ayudes. gracias
Hola buenos días,
Para este tipo de ayudas que se salen de lo que hay disponible en el blog puede enviar un mensaje al centro de soporte técnico con todos los detalles de tu necesidad. Las capturas de pantalla e imágenes ayudan mucho.
https://www.jose-aguilar.com/soporte/
Saludos
Hola!
Me podrías decir cómo usar una base de datos completa de una tienda en otra tienda de prestashop?
He instalado otra versión de prestashop y creado una nueva tienda para ver si así se resuelven unos problemas que tengo, y no quisiera meter de nuevo todos los productos.
He probado modificando el nombre de la base de datos, pero no me deja acceder al panel de control.
Gracias!
Hola buenos días,
Responderle a esta pregunta es bastante complicado. Deberíamos conocer primero las versiones con las que estás haciendo el proceso. Le recomendamos que nos envíe un ticket con toda la información a:
https://www.jose-aguilar.com/soporte/
y allí le indicaremos como podemos proceder.
Saludos
Hola Jose, siempre te sigo un poco los articulos, yo acabo de cojer un proyecto a medias en prestashop con una version antigua o sea la version 1.5 la cuestion es como me aconsejaria que la actualices, y otra cosa es, tengo un producto, pero en el modulo onepagecheckout aparecen detalles y descripcion, yo quiero agregar y de hecho lo hice una pestaña que se llame video que es donde pongo un video relacionado con ese producto, la cuestion es puedo crear un campo mas en la tabla producto para relacionar el video con ese producto, mas que nada creo que poder se puede, pero es aconsejable? es que de prestashop la verdad no se nada llevo 3 dias con ello y me han soltao un proyecto grande a mi solo
Hola buenas tardes,
La actualización es recomendable hacerla con el módulo de actualización en un click de PrestaShop:
http://addons.prestashop.com/es/5496-1-click-upgrade-autoupgrade.html
Poder puedes y es una solución aceptable pero lo recomendable es que hagas una nueva tabla para asociar los videos con los productos. De hecho ya existe algún módulo de pago con el que puedes asociar videos al producto.
Saludos
Hola una consulta, tengo un formulario de registro de pago que es lo mas recomendable realizar para la conexión a BDD conectarla a la de prestashop o una externa si me puedes orientar muchas gracias
Buenos días, necesito ayuda la verdad resulta que todos los productos que tengo en la tienda (prestashop 1.6)pertenecen al un solo proveedor, que asta la fecha no había creado puesto que sólo operaba con el. Pero ahora me dispongo a trabajar con varios más y necesitaría saber como seria la sentencia para agregarle a todos los productos que ahora poseo el proveedor. Muchas gracias de antemano.
Hola buenos días,
Creo que debes hacer un insert en la tabla: ps_product_supplier
Saludos
Hola Buenas Tardes, me gustaría tener la base de datos PrestaShop en SQL SERVER ¿Es posible?
Gracias
Hola buenos días, esa consulta se la deberás hacer a PrestaShop directamente. YO diría que no es posible pero no es seguro. Saludos
[…] necesitáis más información sobre cómo ejecutar sentencias, os propongo que visitéis el artículo de Jose Aguilar que explica cómo trabajar con la clase […]
Buenas tardes,
Estoy intentando integrar prestashop en un programa de gestión que me hice con Filemaker.
Tengo los enlaces a Mysql y en Filemaker puedo ver las tablas, pero no genera las relaciones.
¿Habría forma de ver, en formato listado, las relaciones de prestashop que tengo que crear?
¿lo podría generar con MySQL Workbench?
Muchas gracias
Estoy intentando seguirte pero no consigo actualizar mi BBDD.
El proceso es el siguiente:
Cuando carga la página, se ejecuta este código jquery
$(‘#divId’).load(‘../../price.php’);
setInterval(function(){
$(‘#divId’).load(‘../../price.php’);
}, 3600);
Como ves este código llama a price.php
insert(‘ps_54z_product_shop’, array(
‘price’ => pSQL($name),
));
*/
?>
La primera parte lo que hace es llamar a un archivo JSON que contiene la cotización al segundo.
Nota: No he conseguido llamar al archivo con jquery ya que me da error cross-origin resource (por temas de seguridad parece ser que con javascript no deja cargar archivos de otro domino)
Se que lo ejecuta bien porque no hay errores en la consola y puedo ver el resultado en mi prestashop.
En la segunda parte es la problemática para mi. No sé como actualizar el precio en la BBDD. Por ahora estoy intentando poner un precio cualquiera ej 10 a todos los productos.
Este query me funciona de lujo en MySQL—- UPDATE `ps_54z_product_shop` SET `price`= 10 .
Como puedo mediante Db::getInstance() conseguir mandar el query MySQL UPDATE `ps_54z_product_shop` SET `price`= 10 ?
Muchas gracias
Hola,
Nos tendrías que facilitar el archivo php que ejecutas en el ajax. Yo creo que te falta incluir unos archivos para poder utilizar la clase DB de prestashop pero no soy adivino.
Saludos
Buenas noches.
Primero felicidades, todo lo que leo me parece muy util e interesante.
Mi problema es el siguente, he borrado la raiz de las categorias en la base de datos, osea root de la version 1.6.0.9 de prestashop
cuando intento crear una categoria nueva, no me deja asociarla a ningun indice.
que table Ps_»»»»’ es la deberia contener la información
Un saludo ymuchas gracias.
Deberás volver a crear esas categorías root y la categoría de inicio (id_category=2). Nunca se deben borrar esas categorías. Si tienes una instalación limpia por ahí fijate como lo tiene y copia el contenido de las tablas ps_category_xxx
Necesito leer desde prestashop datos de otra BD. ¿es posible?¿como se haria?, par luego mostrarlos en un modulo que he creado, espero me ayudes. gracias
Si, se puede! Tu puedes conectar con mysqli por ejemplo a la base de datos externa.
Ayudame por favor, necesito insertar los productos a nivel de base de datos ya que es una migración masiva asociada a un conjunto de fatures (YEAR, Modelo, SubModelo, Etc),es para vehiculos, inserte en la tabla ps_product y ps_product_lang y no me aparecen, que otra tabla toca la inserción de productos o hay otra forma de hacero?????, necesito hacerlo así para asociarlo a las caracteristicas o features.
Muchisimas Gracias
ps_feature
…
Hay muchas tablas asociadas a los productos
Buenas tardes para empezar encuentro muy interesante todas las cuestiones que se plantean y sus respuestas.
Yo ya tengo terminada la web y es una web de dropshoping, tengo unas 7000 referencias, las cuales estan todas metidas en la base de datos, las inserte desde prestashop 1.6 con la opcion de importar csv y tuve que hacerlo de 500 en 500 registros porque se me quedaba pillado el prestashop. que es lo que se queda pillado prestashop o mi servidor del hosting?.
pues ahora necesito hacer una sincronizacion entre mi proveedor y mi web para que actualice los productos por lo menos cada 5 horas.
El problema es que no se como guarda en las tablas de la base de datos los datos y la informacion.
Por ejemplo he estado buscando en todas las tablas la dirección url de todas las imagenes de la tienda para eliminarlas todas. Pues no se donde está.
necesito saber donde guarda prestashop toda la información para empezar a programar las actualizaciones de productos y despues ejecutar un CRON en el servidor para que se ejecute cada ciertas horas predefinidas.
Te agradecería mucho que me echaras una mano no quiero poner la tienda visible hasta que no solucione este tema.
Hola buenos días,
Es normal que se quede pillado la importación. Los servidores no suelen aguantar tanto a no ser que se solicite al servicio de hosting la ampliación del tiempo de ejecución.
El cron hay que hacerlo muy cuidadosamente y que solo haga lo necesario, cargar 7000 referencias de un golpe te va a saturar el servidor si o si. Lo suyo es que solo actualice los productos que se han modificado y sin volver a cargar las fotos que es lo que más problemas da.
Toda la información referente a los produtos prestashop las guarda en las tablas que comienzan por PREFIX_product… y sobre las imágenes puede constarte un poco entender su funcnionamiento pero se guardan en base de datos en la tabla PREFIX_image y los archivos en el directorio img/p/, normalmente en subcarpetas.
Espero haberte ayudado,
Saludos
Tengo Prestashop 1.5.6.2 y tengo varios problemas ya que la tienda viene desde la versión 1.3 actualizandose, y deseo crear una tienda «nueva» conservando Productos con sus imágenes, descripción y todo, tambien los clientes con sus contraseñas direcciones, las facturas ya creadas, y usuarios administradores…
mi pregunta es, que tablas debo copiar?
Hola buenas tardes,
Si, cuando una tienda ha sufrido tantas actualizaciones siempre quedan residuos en la base de datos.
Desde mi punto de vista y experiencia creo que es montar un prestashop limpio y realizar una actualización del antiguo a la misma versión del limpio y empezar a pasar las tablas que se deseen mantener.
En tu caso, tan solo deberás pasar todas las tablas que comiencen por:
ps_product
ps_image
ps_customer
ps_address
ps_order
ps_employee
Hola Buenas me gustaría saber cuales son las tablas que se utilizan para los productos y las categorías para poder importarlas con DUMP Gracias.
Hola,
Las tablas de categorias son todas las que empiezan por ps_category…
Y las de productos todas las que empiezan por ps_product…
En el caso de que el prefijo de la base de datos sea ps_
Hola, primerament felicitarte por el blog …ahora voy con mis dudas: estoy empezando a utilizar prestashop y tengo un problema en relacion a la personalizacion de los productos, ya que mi tienda tiene 1000 productos,y lo que he hecho es conectarme a la bd de Prestashop con una clase java y con el conector de mysql he insertado y modificado lo que he considerado correspondiente en las tablas ps_customization_field , customization_field_lang y en ps_product_lang; las tablas anteriores son las que cambian al hacer una personalizacion de producto es por ello que ahi es donde he tocado y sé que esta bien…. MI PREGUNTA ES: Porque los cambios no se aprecian en el panel de administracion?…. tambien he probado a tocar la bd desde phpmyadmin directamente, cambiando el valor del proveedor de un producto(sólo he cambiado el valor 0 por un 3 que es un proveedor que tengo registrado) pero al dirigirme al panel de administracion no se cambia….. podrias explicarme porque es esto ? … Un saludo y gracias de antemano ..
Hola buenas tardes,
Me temo que te falta al menos modificar un campo que hay en la tabla ps_product que se llama customizable o customization. También tendrás que modificar el ps_product_shop posiblemente.
Yo lo que haría en tu caso es personalizar un producto desde el prestashop y revisar las tablas que te comento para que veas las diferencias con el resto de productos.
Espero haberte ayudado,
Saludos
Buenas,
Empiezo a contruir mi primer modulo. Estoy haciendo algo sencillo, coger ciertos valores (arrays) de las tablas estandar de la base de datos por defecto de prestashop e ingresandolos en una tabla propia con otro nombre de id. Ademas, quiero que unicamente copie los que en la tabla origen tengan un id con un valor concreto, sin que este valor tenga que ser copiado a la tabla nueva.
Seria algo asi como…???:
$id = Tools::getValue(‘id_origen_a_copiar’);
$name = Tools::getValue(‘id_destino_en_el_que_se_copiara’);
Db::getInstance()->autoExecute(‘tabla_destino’, array(
‘id_target’ => (int)$id,
‘name’ => pSQL($name),
), ‘INSERT’);
Gracias, un saludo!! INTERESANTE POST, MUY POCA DOCUMENTACION APLICADA A PRESTA
Hola que tal,
El código parece correcto. Lo único que ve extraño es que el name parece estar recibiendo un id numérico cuando posiblemente lo estés guardando con un string. Algo no cuadra.
SAludos
Buenas noches.
Si quisiera modificar algunos articulos desde otra aplicación php lo podria hacer?
si, claro
Hola, tengo una cuestión,
Puedo usar la BB.DD. de prestashop para conectarlo a mi web y vender productos desde mi web? (aun no tengo la web, estoy diseñándolo, es solo una idea). Me gusta la estética de mi web y su diseño y me gustaría usarlo, en vez de la tienda y estética de prestashop. Es decir, la idea es colocar productos de mi web pero que usáramos las variables de prestashop para hacer el seguimiento (compras, el precio de cada productos, etc). Daría de alta los productos en prestashop pero estos, los vería desde mi web. Es posible hacerlo? Muchas gracias, un saludo
Hola, si que es posible, seguramente tendríamos que hacer la integración.
Hola,
queria hacerte una pregunta. llevo algun tiempo con la tienda prestashop y me ocurre algo que no entiendo, aunque quiero pensar que es por el servidor que no me lo permite.
sea como sea el problema que tengo es que cuando quiero poner un producto en «productos destacados» me aparece un error.
he intentado poner esos productos a traves de una instalacion en mi pc (localhost) pero luego cuando voy a ps_features en la base de datos. no aparece nada.
Cuando entramos en un producto y pulsamos en asociaciones. podemos ticar en varias categorias. lo que no es donde se refleja esa asociacion de categorias en la base de datos.
me podria decir que tablas son las relacionadas con esta asociacion de categorias?
muchas gracias
Hola buenas tardes,
Basándome en un prestashop 1.5.x la tabla implicada para los productos destacados en página de inicio es la ps_category_product. Los productos que estén asociados a la categoria inicio (id=2) son los que están en productos destacados.
La tabla ps_feature no tiene nada que ver, en este caso son las características que se le pueden dar opcionalmente a los productos.
Saludos,