Laravel validation 'exist' not working in master-slave DB configuration? - php

I am moving the project to Master-Slave configuration and got a problem, that validation related to DB stopped working for me. Any ideas what I'm missing?
so here is validation part:
$request->validate([
'property_id' => 'required|exists:mysql.property,p_id',
... other validations not related to DB ...
], $error_messages);
file config\database.php :
'mysql' => [
'driver' => 'mysql',
'write' => [
'host' => '196.168.56.211',
],
'read' => [
'host' => '192.168.56.222',
],
'port' => '3306',
'database' => 'project_db',
'username' => 'db_user',
'password' => 'pass123',
'unix_socket' => env('DB_SOCKET'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
\PDO::ATTR_EMULATE_PREPARES => true,
],
this is what i'm reciving:
in file \vendor\laravel\framework\src\Illuminate\Database\Connection.php [663]:
catch (Exception $e) {
throw new QueryException(
$query, $this->prepareBindings($bindings), $e
);
}
SQLSTATE[HY000] [2002] An attempt to establish a connection was
unsuccessful, because The required response was not received from the
other computer within the required time, or the already established
connection was terminated due to the incorrect response of the already
connected computer. (SQL: select count(*) as aggregate from
property where p_id = 2444)
and this is happens when laravel try to connect to 'write' database.
But from MySQL workbench - connecting & editing records fine.
any ideas?

change your config to
'mysql' => [
'write' => [
'host' => '196.168.56.211'
],
'read' => [
'host' => '192.168.56.222',
],
'sticky' => true,
'driver' => 'mysql',
'database' => 'project_db',
'username' => 'db_user',
'password' => 'pass123',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
This ensures that any data written during the request cycle can be immediately read back from the database during that same request
official document read for more info

Related

Laravel: User notification fails to run when executed by the queue due to a InvalidArgumentException : Database [mysql] not configured error

I'm trying to queue notifications in my laravel project. Whenever a notifications is queued it successfully makes a record in the jobs table with the specified delay. However, when the job is executed, it fails due to this error InvalidArgumentException : Database [mysql] not configured. I can schedule regular jobs in the queue which run properly but any notifications I attempt to queue fail. They do work when queueing in sync mode if that matters.
I've also cleared my cache and config php artisan config:clear && php artisan cache:clear
I have database defined in config/queue.php:
'default' => env('QUEUE_CONNECTION', 'database'),
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
...
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
and I have mysql defined in config/database.php
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'url' => '',
'host' => env('DB_HOST', DB_HOST),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', DB_NAME),
'username' => env('DB_USERNAME', DB_USER),
'password' => env('DB_PASSWORD', DB_PASS),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
...
I have dd(config('database.connections')); in my AppServiceProdivder.php which out puts the correct result:
array:4 [
"mysql" => array:15 [
"driver" => "mysql"
"url" => null
"host" => "127.0.0.1"
"port" => "3306"
"database" => "****"
"username" => "****"
"password" => "****"
"unix_socket" => ""
"charset" => "utf8mb4"
"collation" => "utf8mb4_unicode_ci"
"prefix" => ""
"prefix_indexes" => true
"strict" => false
"engine" => "InnoDB"
"options" => []
],
...
]
I have found that when the notification job is executed the database connections are removed and replaced with a default connection which matches my defined mysql connection. However, laravel is looking for a mysql config not default which causes the job to fail.
.env file:
DB_CONNECTION=mysql
DB_PORT=3306
DB_HOST=127.0.0.1
DB_DATABASE=****
DB_USERNAME=****
DB_PASSWORD=****
CACHE_DRIVER=file
#SESSION_DRIVER=database
SESSION_LIFETIME=120
QUEUE_CONNECTION=database
QUEUE_FAILED_DRIVER=database
Here is the stacktrace for the job error:
[2020-12-15 10:09:02] local.ERROR: Database connection [mysql] not configured. {"exception":"[object] (InvalidArgumentException(code: 0): Database connection [mysql] not configured. at /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:152)
[stacktrace]
#0 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(115): Illuminate\\Database\\DatabaseManager->configuration()
#1 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(86): Illuminate\\Database\\DatabaseManager->makeConnection()
#2 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1257): Illuminate\\Database\\DatabaseManager->connection()
#3 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1223): Illuminate\\Database\\Eloquent\\Model::resolveConnection()
#4 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1052): Illuminate\\Database\\Eloquent\\Model->getConnection()
#5 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(969): Illuminate\\Database\\Eloquent\\Model->newBaseQueryBuilder()
#6 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1005): Illuminate\\Database\\Eloquent\\Model->newModelQuery()
#7 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1031): Illuminate\\Database\\Eloquent\\Model->newQueryWithoutScopes()
#8 /var/www/vhost1/master/vendor/illuminate/queue/SerializesAndRestoresModelIdentifiers.php(114): Illuminate\\Database\\Eloquent\\Model->newQueryForRestoration()
EDIT:
Output from \Log::info($this->app['config']['database.connections']); inside DatabaseManager.php line 149
[2020-12-16 09:19:26] local.INFO: array (
'default' =>
array (
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => '****',
'username' => '****',
'password' => '****',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
)
[2020-12-16 09:19:26] local.INFO: array (
'default' =>
array (
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => '****',
'username' => '****',
'password' => '****',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
)
I finally figured it out. Another developer was resetting the database connections in a legacy section of our code base outside of the original laravel project. I'm not sure how its effecting the notification queue from where it's located but regardless it was the root of the issue. I doubt anyone else will run into this same scenario but if you do, I fixed it by re-adding my mysql connection with the config name specified.
$this->capsule->addConnection([
'driver' => 'mysql',
'url' => '',
'host' => DB_HOST,
'port' => '3306',
'database' => DB_NAME,
'username' => DB_USER,
'password' => DB_PASS,
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => 'InnoDB',
'options' => [],
], 'mysql');```

Illuminate Database connectivity with mysql router

I'm using Laravel's illuminate database library outside laravel with jessengers mongodb.
My requirement is multiple database connectivity through illuminate database.
Currently, I've added two connection one mysql and one mongodb.
To split the database load, I need to connect to mysql router instead of mysql db server directly. Also, in that I want one only for Read operation and one for Read/Write operation.
Kindly help me out on this.
Thanks in advance.
Current connections
$db = new Capsule;
$db->addConnection([
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'test',
'username' => 'test',
'password' => 'test#123#',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
], "default");
$db->addConnection([
'driver' => 'mongodb',
'host' => '127.0.0.1',
'port' => 27017,
'database' => 'test',
'username' => null,
'password' => null,
'options' => []
], "mongodb");
$db->getDatabaseManager()->extend('mongodb', function ($config) {
return new Connection($config);
});
$db->setEventDispatcher(new Dispatcher(new Container));
$db->setAsGlobal();
$db->bootEloquent();
I need to replace one mysql connection with two mysql connection for Read and Read/Write operation through mysql router.
You can define read/write options separately with either mysql host or mysql router host and port
$db->addConnection([
'driver' => 'mysql',
'read' => [
'host' => '<mysql_router_host_ip>',
'port' => '<mysql_router_host_port>'
],
'write' => [
'host' => '<mysql_router_host_ip>',
'port' => '<mysql_router_host_port>'
],
'database' => '<mysql_database>',
'username' => '<mysql_database_user>',
'password' => '<mysql_database_password>',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
], "mysql");

Laravel 4.2 Session Database Driver Read / Write Host

I configured the way I separate the database to read and write.
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
But now, I want to change the database driver in the session and I want to be able to read and write operations to a single host of the session value.
How can I only run on a single host in the session process without disturbing the above structure?
I think I found a solution.
We are adding a new connection into the first database.php connections.
'session' => array(
'host' => "HOST_NAME",
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
then we give the name of the connection a little bit before we install the connection value in session.php file.
'connection' => "session",
Thats it.

Dynamic database connection in Laravel

I know that in Laravel you can use multiple database connections by specifying them in the config/database.php file, then using DB::connection('my_conn_name'), but is there anyway to use a connection that is not specified in the config/database.php file?
I am writing an archiving application, so the user can specify what connection they would like to use for the process (host, user and password), and I am hoping that I can return the results from show databases for the supplied connection.
After the user has specified the db parameters you could store it in a session to populate a custom connection at config/database.php:
'connections' => [
'mysql' => [
'...'
],
'testing' => [
'...'
],
'custom' => [
'driver' => 'mysql',
'host' => session()->get()->db_host,
'database' => session()->get()->db_database,
'username' => session()->get()->db_username,
'password' => session()->get()->db_password,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
]
]

Connect to Redshift Database from Laravel 5 using Pgsql Driver?

I was wondering if anyone knew whether the above was likely to be achievable or if I'm doing something nonsensical. These connection details work to an RDS (i.e. blah.blah.eu-west-1.rds.amazonaws.com) database:
'db1' => [
'driver' => 'pgsql',
'host' => env('DB_HOST_BRAIN'),
'database' => env('DB_DATABASE_BRAIN'),
'username' => env('DB_USERNAME_BRAIN'),
'password' => env('DB_PASSWORD_BRAIN'),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'xyz_admin',
],
but these do not work to a Redshift (i.e. blah.blah.eu-west-1.redshift.amazonaws.com) database:
'db2' => [
'driver' => 'pgsql',
'host' => env('DB_HOST_PINKY'),
'database' => env('DB_DATABASE_PINKY'),
'username' => env('DB_USERNAME_PINKY'),
'password' => env('DB_PASSWORD_PINKY'),
'port' => env('DB_PORT_PINKY'),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'xyz',
],
Assuming all the details are correct, is there a compelling reason why this is never going to work? Is there any way I can make it work?
As long as the environment variables are correct, your config works for connecting to Redshift:
$take_over_the_world = DB::connection('db2')->select('SELECT tonight FROM going_to_do');

Categories