Publicidad

Poner prefijos a las tablas de base de datos en Laravel


Por Alex el 26/02/2025, Comentar el artículo

Comparte este artículo:      




Al crear un proyecto de Laravel incluye una serie de tablas para diferentes funcionalidades cache, usuarios, jobs … pero qué pasa si yo ya tengo mis tablas con esos nombres y no quiero borrarlas o que se mezclen …


Tenemos la opción de poner un prefijo a estas tablas para diferenciarlas y poder trabajar con tablas con prefijo o sin él si ya tenemos nuestra propia base de datos.

Para ver el funcionamiento voy a crear un ejemplo con Laravel 11 y una base de datos de pruebas

1) Preparando el entorno con Laravel

Lo primero que hay que hacer es crear el proyecto en Laravel, desde el terminal ejecutamos el comando

composer create-project laravel/laravel test_prefix '11.*'

Y crea una base de datos (prefix) con la siguiente estructura de ejemplo para las pruebas, en el github he dejado el proyecto

Estructura de la base de datos de pruebas


2) Cómo son las tablas que añade Laravel

Al crear el proyecto de Laravel crea las siguientes migraciones por defecto

Migraciones inicial del proyecto en Laravel

Que se pueden encontrar en la ruta database/migrations y son para:

  • La gestión de usuarios:
    • users
    • password_reset_tokens
    • sessions
  • Para el cache:
    • cache
    • cache_locks
  • Para los trabajos:
    • jobs
    • jobs_batches
    • failed_jobs
Esta tablas se crearán cuando se ejecuten por primera vez las migraciones

Pero antes de ejecutar las migraciones vamos a añadir un prefijo


3) Cómo añadir un prefijo a las tablas de Laravel

Para añadir un prefijo vamos al fichero de configuración de base de datos config/databases.php y en el driver que vamos a utilizar de base de datos, en el ejemplo utilizo MySql, modificamos el campo prefix

'mysql' => [
            'driver' => 'mysql',
            'url' => env('DB_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'laravel'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => env('DB_CHARSET', 'utf8mb4'),
            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
            'prefix' => 'lara_',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

Y voy añadir el prefix lara_ esto hará que a todas las tablas utilicen el prefijo:

  • No es necesario modificar las migraciones: Laravel aplicará automáticamente el prefijo a todas las tablas.
  • Las consultas de Eloquent respetan el prefijo: No es necesario modificar los modelos.
  • Si usas consultas SQL manuales, se tiene que incluir el prefijo:
    
    DB::table('users')->get(); // Laravel agregará el prefijo automáticamente 
    DB::select("SELECT * FROM myapp_users"); // Aquí debes incluir el prefijo manualmente
    
Y ahora ejecutamos las migraciones para que se creen las tablas de laravel en nuestra base de datos

php artisan migrate

Y si ahora vamos a ver la estructura de la base de datos vemos que se han creado las nuevas tablas con el prefijo lara_

Estructura de la base de datos de pruebas con las tablas de laravel con prefijo


4) Cómo trabajar con tablas sin prefijo

Pero en nuestra base de datos tenemos tablas sin prefijo y queremos que sigan así … ¿cómo podemos trabajar con ellas? o crear nuevas tablas que no sean de laravel y sin prefijo

Para las pruebas creamos un comando que liste los datos de la tabla Customer

php artisan make:command ListCustomers

Y añadir el siguiente código

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Models\Customer;

class ListCustomers extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'customers:list';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'List all customers from the database';

    /**
     * Execute the console command.
     */
    public function handle()
    {
       //$customers = Customer::all();

        # Descomentar para probar el error de la tabla no encontrada
        $customers = DB::table('customer')
            ->select('customer_id', 'first_name', 'last_name', 'email', 'active')
            ->get();
        print_r( $customers);

        # Descomentar para probar Eloquient utilizando el modelo con conexion especifica
        // $customers = Customer::select('customer_id', 'first_name', 'last_name', 'email', 'active')->get();
        // print_r( $customers->toArray());

        # Descomentar para pronar query RAW
        // $customers = DB::select("SELECT * FROM customer");
        // print_r( $customers);

        # Descomentar para probar con Query Builder con conexion especifica
        // $customers = DB::connection('mysql_no_prefix')->table('customer')->get();
        // print_r( $customers);

    }
}

Y si ejecutáis el comando dará este error:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'prefix.lara_customer' doesn't exist (Connection: mysql, SQL: select `customer_id`, `first_name`, `last_name`, `email`, `active` from `lara_customer`)

¿ Porque ejecuta las consultas contra las tablas con prefijo ?

Por defecto Laravel siempre trabajará con las tablas con prefijo (si existe), para trabajar con tablas que no tienen prefijo se puede hacer de varias formas:

1) creando una segunda conexión en el fichero config/databases.php sin el prefijo

'mysql_no_prefix' => [
            'driver' => 'mysql',
            'url' => env('DB_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'laravel'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => env('DB_CHARSET', 'utf8mb4'),
            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

Y creamos un modelo

php artisan make:model Customer

Y ponemos el siguiente código

protected $connection = 'mysql_no_prefix';

protected $table = 'customer';

Con esto hacemos que utilice la conexión que no tiene prefijo

2) Otras formas de utilizar las tablas sin prefijo es con una query raw con un select de toda la vida

DB::select("SELECT * FROM customer");



3) por último podríamos optar a utilizar Query Builder especificando la conexión

$customers = DB::connection('mysql_no_prefix')->table('customer')->get();

Esto también es aplicable a las migraciones.

Por ejemplo si queremos crear una tabla que no tenga prefijo podemos utilizar la conexión mysql_no_prefix como se muestra en el siguiente código

Schema::connection('mysql_no_prefix')->create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->decimal('price', 8, 2);
            $table->timestamps();
        });

O podemos utilizar una consulta raw

DB::statement("
            CREATE TABLE products_raw (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(255) NOT NULL,
                price DECIMAL(8,2) NOT NULL,
                created_at TIMESTAMP NULL DEFAULT NULL,
                updated_at TIMESTAMP NULL DEFAULT NULL
            )
        ");

Estos ejemplo también están en el proyecto en github

5) Conclusión

Esta opción que tiene Laravel de utilizar prefijos en las tablas y multiples conexiones a la base de datos nos puede ser útil no solo para diferenciar tablas dentro de una misma base de datos sino para poder trabajar con diferentes bases de datos donde se aplicaría el mismo principio de dos conexiones.

Laravel siempre utilizará los prefijos si estan definidos y para no utilizarlos lo mejor es utilizar una conexión a base de datos diferente y sin prefijo o una consulta raw.

En el Comando, ListCustomers, para realizar las pruebas hay varias opciones comentadas para realizar diferentes pruebas según la forma de conectarse a la base de datos.

El esquema de la base de datos para poder crearla esta en el directorio _datos/sql/schema.sql dentro del proyecto.


Y esto es todo, feliz programming!!!
Saludos
Alex
:-)
/


Si te ha gustado el artículo compartelo en:      




Añadir un comentarios:

Nombre:
Email: (no se publica el email)




SIGUENOS EN


ARCHIVO

Publicidad

.