Que vamos ver en este artículo
1) Preparando el entorno con Laravel
Lo primero que hay que hacer es crear el proyecto en Laravel, desde el terminal ejecutamos el comandocomposer 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
2) Cómo son las tablas que añade Laravel
Al crear el proyecto de Laravel crea las siguientes migraciones por defecto
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
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
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_
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 prefijoPara 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
:-)
/