Jump to content

(SOLUCIONADO) ¿Cómo crear claves ajenas (foreign keys) en la base de datos?


oddworldng

Recommended Posts

Hola,

 

Estoy creando un módulo que requiere el uso de base de datos, y en especial el uso de una clave ajena (foreign key). He buscado y no consigo encontrar ningún ejemplo en los propios módulos de Prestashop ni en ninguna documentación.

 

Tengo esta función y quiero poner id_employee como clave ajena de id_employee de la tabla ps_employee:

public function installDb()
{
	return (
	Db::getInstance()->execute('
	CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'employee_control` (
		`id` INT UNSIGNED NULL AUTO_INCREMENT PRIMARY KEY,
		`id_employee` INT(2) UNSIGNED NOT NULL,
		`date` DATE NULL,
		`hours` INT(2) UNSIGNED NULL,
		`description` TEXT NULL,
		INDEX (`id`)
	) ENGINE = '._MYSQL_ENGINE_.' CHARACTER SET utf8 COLLATE utf8_general_ci;')
	);
}

¿Alguna idea?

 

 

Gracias de antemano :)

Edited by oddworldng (see edit history)
Link to comment
Share on other sites

Una opción, create un fichero llamado:

install.sql

en el modulo.
 
Al ser un fichero sql puedes crear la tabla y una foreign key como toda la vida.
 


Despues en el php del módulo ejecuta ese sql, por ejemplo así:

if ($keep)
		{
if (!file_exists(dirname(__FILE__).'/'.self::INSTALL_SQL_FILE))
				return false;
			else if (!$sql = file_get_contents(dirname(__FILE__).'/'.self::INSTALL_SQL_FILE))
				return false;
			$sql = str_replace(array('PREFIX_', 'ENGINE_TYPE'), array(_DB_PREFIX_, _MYSQL_ENGINE_), $sql);
			$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
			foreach ($sql as $query)
				if (!Db::getInstance()->execute(trim($query)))
					return false; 

}

Dentro de la función:

public function install($keep = true)

Esto esta sacado del modulo de comentarios que lleva Prestashop, fijate que lleva su fichero sql para crear las tablas:

/modules/productcomments/install.sql

y dentro del fichero:

/modules/productcomments/productcomments.php

ejecuta ese fichero en la parte del código donde te he pegado.

Al principio del *.php (Despues de declarar la clase, donde se declaran las variables) del modulo añade esto:
 

	const INSTALL_SQL_FILE = 'install.sql';

para indicar que vas a trabajar con es fichero. (Luego como ves se usa esa variable constante) 

Edited by nadie (see edit history)
Link to comment
Share on other sites

Una opción, create un fichero llamado:

install.sql
en el modulo.

 

Al ser un fichero sql puedes crear la tabla y una foreign key como toda la vida.

 

 

 

Despues en el php del módulo ejecuta ese sql, por ejemplo así:

if ($keep)
		{
if (!file_exists(dirname(__FILE__).'/'.self::INSTALL_SQL_FILE))
				return false;
			else if (!$sql = file_get_contents(dirname(__FILE__).'/'.self::INSTALL_SQL_FILE))
				return false;
			$sql = str_replace(array('PREFIX_', 'ENGINE_TYPE'), array(_DB_PREFIX_, _MYSQL_ENGINE_), $sql);
			$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
			foreach ($sql as $query)
				if (!Db::getInstance()->execute(trim($query)))
					return false; 

}
Dentro de la función:

public function install($keep = true)
Esto esta sacado del modulo de comentarios que lleva Prestashop, fijate que lleva su fichero sql para crear las tablas:

/modules/productcomments/install.sql
y dentro del fichero:

/modules/productcomments/productcomments.php
ejecuta ese fichero en la parte del código donde te he pegado.

 

Al principio del *.php (Despues de declarar la clase, donde se declaran las variables) del modulo añade esto:

 

	const INSTALL_SQL_FILE = 'install.sql';

para indicar que vas a trabajar con es fichero. (Luego como ves se usa esa variable constante)

 

 

Actualizo mi mensaje.

 

Logicamente ahora en el install sql, ejecutas todas las consultas bien de actualización, creación tablas, etc...

 

Ejemplo:

 

ALTER TABLE `PREFIX_employee_control`
ADD CONSTRAINT `id_employee`
FOREIGN KEY (`id_employee`)
REFERENCES `PREFIX_employee` (`id_employee`)
ON DELETE CASCADE ON UPDATE CASCADE;

Logicamente en el mismo install.sql puedes declarar tambien la tabla ps_employee_control que normalmente se debe crear antes de ejecutar el alter table.

 

Y creo que tampoco necesitarias el alter table, ya que en la misma declaración de la tabla puedes asignar la foreign key..

 

CREATE TABLE xxxxx
(
declaracion campos
FOREIGN KEY (campo_tabla_actual) REFERENCES tabla_donde_enlazas(campo_tabla_donde_enlazas_relaccionas)
) TYPE = XXXXX
  • Like 1
Link to comment
Share on other sites

Gracias nadie, diste con la solución.

 

Simplemente le añades la siguiente línea a lo que ya tenía y funciona:

FOREIGN KEY (campo_tabla_actual) REFERENCES tabla_donde_enlazas(campo_tabla_donde_enlazas_relaccionas)

El resultado es el siguiente:

public function installDb()
{
	return (
	Db::getInstance()->execute('
	CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'employee_control` (
		`id` INT UNSIGNED NULL AUTO_INCREMENT PRIMARY KEY,
		`id_employee` INT(2) UNSIGNED NOT NULL,
		`date` DATE NULL,
		`hours` INT(2) UNSIGNED NULL,
		`description` TEXT NULL,
		FOREIGN KEY (id_employee) REFERENCES ps_employee(id_employee),
		INDEX (`id`)
	) ENGINE = '._MYSQL_ENGINE_.' CHARACTER SET utf8 COLLATE utf8_general_ci;')
	);
}

Y aquí una captura de Phpmyadmin de cómo quedan las relaciones hechas:

 

30m1qpy.jpg

Link to comment
Share on other sites

Gracias nadie, diste con la solución.

 

Simplemente le añades la siguiente línea a lo que ya tenía y funciona:

FOREIGN KEY (campo_tabla_actual) REFERENCES tabla_donde_enlazas(campo_tabla_donde_enlazas_relaccionas)

El resultado es el siguiente:

public function installDb()
{
	return (
	Db::getInstance()->execute('
	CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'employee_control` (
		`id` INT UNSIGNED NULL AUTO_INCREMENT PRIMARY KEY,
		`id_employee` INT(2) UNSIGNED NOT NULL,
		`date` DATE NULL,
		`hours` INT(2) UNSIGNED NULL,
		`description` TEXT NULL,
		FOREIGN KEY (id_employee) REFERENCES ps_employee(id_employee),
		INDEX (`id`)
	) ENGINE = '._MYSQL_ENGINE_.' CHARACTER SET utf8 COLLATE utf8_general_ci;')
	);
}

Y aquí una captura de Phpmyadmin de cómo quedan las relaciones hechas:

 

30m1qpy.jpg

 

Un placer ayudarte y servirte !

 

PD: Como he visto que has añadido la palabra  "Solucionado" al título del tema, procedo a cerrar el tema.

 

Saludos !

 

Feliz año nuevo !

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...