I'm developing a Multi Tenant with Laravel v5.7 and I'm successful in sending queue emails, since my models have the property 'connection' defined.
But when trying to send, for example, an email using the Jobs class, the same fails and informs that the table of model does not exist.
From what error recorded in the table 'failed_jobs', even with the property 'connection' defined, it appears that the Job nevertheless tries to connect to the main database and not to the specified database of the property.
Is there any way to specify in Job which database to use, since the same is informed in the model?
database.php
'connections' => [
'others' => ['...']
'TENANT001' => [
'driver' => 'mysql',
'database' => env('TENANT001_DATABASE', ''),
'host' => env('TENANT001_HOSTNAME', ''),
'port' => env('DB_PORT', '3306'),
'username' => env('TENANT001_USERNAME', 'forge'),
'password' => env('TENANT001_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
],
Sample Model
class Template extends Model
{
/**
* The database name used by the model.
*
* #var string
*/
protected $connection = 'TENANT001';
}
failed_jobs
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'main_database.templates' doesn't exist in /www/samba/laravel.local/vendor/laravel/framework/src/Illuminate/Database/Connection.php:326
I guess you are trying to access second connection TENANT001 in Template Model.
class Template extends Model
{
/**
* The database name used by the model.
*
* #var string
*/
protected $connection = 'TENANT001';
protected $table='templates';
}
After that in your config/database.php
'connections' => [
'others' => ['...']
'TENANT001' => [
'driver' => 'mysql',
'database' => env('TENANT001_DATABASE', ''),
'host' => env('TENANT001_HOSTNAME', ''),
'port' => env('DB_PORT', '3306'),
'username' => env('TENANT001_USERNAME', 'forge'),
'password' => env('TENANT001_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
Or you can use connection in the queue.php
'database' => [
'connection' => 'TENANT001'
'driver' => 'mysql',
'table' => 'jobs',
'queue' => 'default',
'expire' => 60,
],
And clear the cache once you update .env files.
php artisan config:cache
And check you have define everything correctly in .env and table exists.
Thanks
Related
I have multiple databases and as a model considers default connection when invoked from a route model binding, it says table not found. How can i bind the model in a resource controller edit/update method as a part of Route Model binding to consider the current connection and not the default connection?
PS - I cannot declare $connection on the model because, i won't know which database it will be accessing at a said moment.
You can use a route middleware to set the database connection for particular routes. To do this you will need to set up your connections in your database config, and then add the middleware.
I use a similar setup in a multi-tenant application to manage system vs tenant database connections. Database config:
'connections' => [
'system' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'lms'),
'username' => env('DB_USERNAME', 'lms'),
'password' => env('DB_PASSWORD', 'lms'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'tenant' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => '',
'username' => '',
'password' => '',
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
],
The middleware in my example enforced the use of a database defined as tenant.
use Closure;
use Illuminate\Support\Facades\Config;
class EnforceTenancy
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
Config::set('database.default', 'tenant');
return $next($request);
}
}
You can then register the middleware in the kernel.php $routeMiddleware array
'tenancy.enforce' => \App\Http\Middleware\EnforceTenancy::class,
and then apply the middleware in your route file for any route that requires the second db.
Using sqlsrv driver, I have issues on using Laravel Validator on a database with a defined schema.
I have no problem accessing the database on any model using the line
protected $table = 'dba.users'
but when I use it on a Validator
return Validator::make($data, [
'name' => 'required|string|max:255|unique:dba.users',
]);
it yields error:
Database [dba] not configured.
i tried using
return Validator::make($data, [
'name' => 'required|string|max:255|unique:sqlrv.dba.users',
]);
but it yields
Invalid object name 'app.users'. (SQL: select count(*) as aggregate from
[app].[users] where [name] = test
where to start?
If this is the only db connection you have you don't need to specify the db so you can do something like:
return Validator::make($data, [
'name' => 'required|string|max:255|unique:users',
]);
However if you are using multiple databases you need to make sure you have specified the names of those databases in your config/database.php file. Take a look at that file and look here https://laravel.com/docs/5.6/database#using-multiple-database-connections. The documentation isn't that clear so I'll outline it more below.
In your database.php file you will find a connections array. Add in your dba connection like so:
'connections' => [
'dba' => [
'driver' => 'mysql',
'host' => env('DB_HOST_2', '127.0.0.1'),
'port' => env('DB_PORT_2', '3306'),
'database' => env('DB_DATABASE_2', 'forge'),
'username' => env('DB_USERNAME_2', 'forge'),
'password' => env('DB_PASSWORD_2', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
]
In your .env file set the new values shown above.
Your database.php file tells laravel what database connections you have and where to look for them. After you have done this your validator will know where to look when you specify a database.
How to connect two database in laravel-5 and how to get data from db.
I know two one thing for that
In config/database set like this.
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'larashop'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'mysql2' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'larashop2'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
Using Query you can define a connection on the Query Builder:
$users = DB::connection('mysql2')->select('your query');
Using Eloquent
You can also define which connection to use in your Eloquent models as well!
<?php
class SomeModel extends Eloquent {
protected $connection = 'mysql2';
}
You can also define the connection at runtime via the setConnection method.
<?php
class SomeController extends BaseController {
public function someMethod()
{
$someModel = new SomeModel;
$someModel->setConnection('mysql2');
$something = $someModel->find(1);
return $something;
}
}
I have find the issue of connect 2 database in laravel.
If any body wants two work with 2 database then config as par above suggestion and remove database configuration from .env file which is located at root.
I have tried and I am working with 2 database.
I want to store multiple database connection in my current laravel db.
i need to connect these via dropdown and generate reports on the fly.
what is the best way to configure this
You can just create a table "connection(strings)" in your 1st db and create a model for that table.
After that you can do something like this:
$selected = Connection::query()->where('name', 'fromdropdown')->first();
$connection = $selected;
config(['database.connections.data' => array(
'driver' => 'sqlsrv',
'host' => $connection['Database_Server'],
'database' => $connection['Database_Name'],
'username' => $connection['Database_User'],
'password' => $connection['Database_Pass']
)]);
DB::setDefaultConnection('data');
You can set multiple database connections in the app/config/database.php file.
Example:
'default' => 'mysql',
'connections' => array(
# Our primary database connection
'mysql' => array(
'driver' => 'mysql',
'host' => 'host1',
'database' => 'database1',
'username' => 'user1',
'password' => 'pass1'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Our secondary database connection
'mysql2' => array(
'driver' => 'mysql',
'host' => 'host2',
'database' => 'database2',
'username' => 'user2',
'password' => 'pass2'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
)
And then just use the connection name in your query:
$users = DB::connection('mysql2')->select(...);
Do i need to create multiple connection to access different database/schema. Cant I use with one dbconnection. Is there a way to pass the database name in the laravel eloquent or db builder? Currently in raw php i use one connection to query the different schema.
Create different connections to your database.php file and then pass them to your eloquent models.
'mysql1' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => 'db1',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
// connection 2
'mysql2' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => 'db2',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
Suppose i have model User.php uses mysql connection named mysql1
inside my model i will add :
protected $connection = 'mysql1';
if i want to use mysql connection named mysql2
then i will use
protected $connection = 'mysql2';
Here i am setting connections statically in to models.
In Eloquent, I use DB:connection() to set my named connection, like so:
$query = DB::connection('db_connection_name')->table($this->table)
If you weren't aware, the database connections are named in the config app/config/database.php