Related
This question already has answers here:
How to use multiple databases in Laravel
(7 answers)
Closed last month.
I'm developing a project where I need to use multiple databases in Laravel. The first database works like a charm (MySQL) but I can't get the framework to recognize the SQLite DB. The error that shows up is this:
Illuminate \ Database \ QueryException
Database (sqlite) does not exist. (SQL: PRAGMA foreign_keys = ON;)
Here is my .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sitio1
DB_USERNAME=root
DB_PASSWORD=
DB_CONNECTION_SECOND=sqlite
DB_DATABASE_SECOND=/Users/imac/CleverOctopusBDD/database/Sitio2.sqlite
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=
and here is my database.php
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_CONNECTION_SECOND', database_path('Sitio2.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'sitiocentral'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
]) : [],
],
And the location of my .sqlite file is this -> database -> Sitio2.sqlite
I've doing some research and I don't really know what am I doing wrong. If you are wondering, this is how one of my sqlite db model looks...
class Client2 extends Model
{
protected $connection = 'sqlite';
protected $fillable = [
'name', 'email', 'phone', 'address'
];
protected $table = 'Client2';
protected $primaryKey = 'idClient';
public $timestamps = false;
}
I hope you can help me out here because I have found information about multiple MySQL connections but not with SQLite, I appreciate any tips given.
EDIT: I just needed to pass the full path to 'database' => env('DB_DATABASE_SECOND', database_path('Sitio2.sqlite')),
does it work if you put the full path to your sqlite file in the database config like this?
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => '/Users/imac/CleverOctopusBDD/database/Sitio2.sqlite',
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
I'm using Laravel, I'm working in a Login System, but in register page, when confirm button is clicked, I get the message: "Database [mydatabase] not configured."
My database.php file:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'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'),
]) : [],
],
My .env file:
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=mydatabasename
DB_USERNAME=root
DB_PASSWORD=
My system and database are in a debian 9 server, and I programming in VS Code in my Windows Client with a extension remote for VSCode called SFTP. My database don't have password for now.
it may be an external access error to mysql, my version of MySQL is 10.4.11 and I am using it on the Debian 9 server with the latest current XAMPP version, and I don't know how to release external access to mysql in XAMPP, because in the my.cnf file there is no bind_address field.
This is just a hypothesis, I came here because I tried everything on Google and nothing works.
Thanks for listening! =D
Edit:
When I run the command "php artisan migrate":
root#LARAVEL:~/Projetos/SistemaX# php artisan migrate
Warning: PHP Startup: Unable to load dynamic library 'zip.so' (tried: /opt/lampp /lib/php/extensions/no-debug-non-zts-20190902/zip.so (/opt/lampp/lib/php/extensi ons/no-debug-non-zts-20190902/zip.so: wrong ELF class: ELFCLASS32), /opt/lampp/l ib/php/extensions/no-debug-non-zts-20190902/zip.so.so (/opt/lampp/lib/php/extens ions/no-debug-non-zts-20190902/zip.so.so: cannot open shared object file: No suc h file or directory)) in Unknown on line 0
InvalidArgumentException : Database [mydatabase] not configured.
at /root/Projetos/SistemaX/vendor/laravel/framework/src/Illuminate/D atabase/DatabaseManager.php:152
148| // If the configuration doesn't exist, we'll throw an exception and bail.
149| $connections = $this->app['config']['database.connections'];
150|
151| if (is_null($config = Arr::get($connections, $name))) {
> 152| throw new InvalidArgumentException("Database [{$name}] not configured.");
153| }
154|
155| return (new ConfigurationUrlParser)
156| ->parseConfiguration($config);
Exception trace:
1 Illuminate\Database\DatabaseManager::configuration("mydatabase")
/root/Projetos/SistemaX/vendor/laravel/framework/src/Illuminate/ Database/DatabaseManager.php:115
2 Illuminate\Database\DatabaseManager::makeConnection("mydatabase")
/root/Projetos/SistemaX/vendor/laravel/framework/src/Illuminate/ Database/DatabaseManager.php:86
Please use the argument -v to see more details.
My code (RegisterController.php):
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/painel';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
public function index() {
return view('admin.register');
}
public function register(Request $request) {
$data = $request->only([
'name',
'email',
'password',
'password_confirmation'
]);
$validator = $this->validator($data);
if ($validator->fails()) {
return redirect()->route('register')
->withErrors($validator)
->withInput();
}
$user = $this->create($data);
Auth::login($user);
return redirect()->route('admin');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:100'],
'email' => ['required', 'string', 'email', 'max:100', 'unique:users'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
My database on mysql (mysql -uroot; show databases;):
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| phpmyadmin |
| mydatabase |
+--------------------+
Edit (My full database.php file):
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'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'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
];
Did you create the database and run Laravel's migrations?
To check if your database exist on your server, login to MySQL on your server and list all databases:
mysql -u yourusername -p
show databases;
Your Laravel database "mydatabasename" should be listed here. If not, you'll have to create it on your server. Since it's not specific to Laravel, I will let you search how to do that.
Once your database exists, you will have to run Laravel's migrations command to create the database tables relevant to your Laravel application:
php artisan migrate
Have done Master Slave configuration as per official Yii2 documentation. Below is actual configuration look like,
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=1.1.1.1;dbname=master_db',
'username' => 'user',
'password' => 'password',
'charset' => 'utf8',
'enableSchemaCache' => true,
'schemaCacheDuration' => 10,
'schemaCache' => 'cache',
'slaveConfig' => [
'username' => 'slave_user',
'password' => 'slave_password',
'charset' => 'utf8',
'attributes' => [
// use a smaller connection timeout
PDO::ATTR_TIMEOUT => 10,
],
'enableSchemaCache' => true,
'schemaCacheDuration' => 10,
'schemaCache' => 'cache',
],
'slaves' => [
['dsn' => 'mysql:host=2.2.2.2;dbname=slave_db']
],
],
It always connect master database even if slave server is up and reachable.
Surprisingly replacing current master config with slave one works, moreover if try to connect slave database from command line it get connected in a moment but unable to achieve same with above configuration.
Wondering if there is any parameters missing in configuration or any other way to get things working like ideal read write splitting?
issue was resolved by adding connection class in the slaveConfig,
'class' => 'yii\db\Connection'
I want to combine multiple databases in my system. Most of the time the database is MySQL; but it may differ in future i.e. Admin can generate such a reports which is use source of heterogeneous database system.
So my question is does Laravel provide any Facade to deal with such situations? Or any other framework have more suitable capabilities for problem is?
Tested versions (Updated)
Version
Tested (Yes/No)
4.2
No
5
Yes (5.5)
6
No
7
No
8
Yes (8.4)
9
Yes (9.2)
Define Connections
Using .env >= 5.0 (or higher)
In .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mysql_database
DB_USERNAME=root
DB_PASSWORD=secret
DB_CONNECTION_PGSQL=pgsql
DB_HOST_PGSQL=127.0.0.1
DB_PORT_PGSQL=5432
DB_DATABASE_PGSQL=pgsql_database
DB_USERNAME_PGSQL=root
DB_PASSWORD_PGSQL=secret
In config/database.php
'mysql' => [
'driver' => env('DB_CONNECTION'),
'host' => env('DB_HOST'),
'port' => env('DB_PORT'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
],
'pgsql' => [
'driver' => env('DB_CONNECTION_PGSQL'),
'host' => env('DB_HOST_PGSQL'),
'port' => env('DB_PORT_PGSQL'),
'database' => env('DB_DATABASE_PGSQL'),
'username' => env('DB_USERNAME_PGSQL'),
'password' => env('DB_PASSWORD_PGSQL'),
],
Note: In pgsql, if DB_username and DB_password are the same, then you can use env('DB_USERNAME'), which is mentioned in .env first few lines.
Without .env <= 4.0 (or lower)
app/config/database.php
return array(
'default' => 'mysql',
'connections' => array(
# Primary/Default database connection
'mysql' => array(
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'mysql_database',
'username' => 'root',
'password' => 'secret'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Secondary database connection
'pgsql' => [
'driver' => 'pgsql',
'host' => 'localhost',
'port' => '5432',
'database' => 'pgsql_database',
'username' => 'root',
'password' => 'secret',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
]
),
);
Schema / Migration
Run the connection() method to specify which connection to use.
Schema::connection('pgsql')->create('some_table', function($table)
{
$table->increments('id'):
});
Or, at the top, define a connection.
protected $connection = 'pgsql';
Query Builder
$users = DB::connection('pgsql')->select(...);
Model (In Laravel >= 5.0 (or higher))
Set the $connection variable in your model
class ModelName extends Model { // extend changed
protected $connection = 'pgsql';
}
Eloquent (In Laravel <= 4.0 (or lower))
Set the $connection variable in your model
class SomeModel extends Eloquent {
protected $connection = 'pgsql';
}
Transaction Mode
DB::transaction(function () {
DB::connection('mysql')->table('users')->update(['name' => 'John']);
DB::connection('pgsql')->table('orders')->update(['status' => 'shipped']);
});
or
DB::connection('mysql')->beginTransaction();
try {
DB::connection('mysql')->table('users')->update(['name' => 'John']);
DB::connection('pgsql')->beginTransaction();
DB::connection('pgsql')->table('orders')->update(['status' => 'shipped']);
DB::connection('pgsql')->commit();
DB::connection('mysql')->commit();
} catch (\Exception $e) {
DB::connection('mysql')->rollBack();
DB::connection('pgsql')->rollBack();
throw $e;
}
You can also define the connection at runtime via the setConnection method or the on static method:
class SomeController extends BaseController {
public function someMethod()
{
$someModel = new SomeModel;
$someModel->setConnection('pgsql'); // non-static method
$something = $someModel->find(1);
$something = SomeModel::on('pgsql')->find(1); // static method
return $something;
}
}
Note: Be careful about building relationships with tables across databases! It is possible to do, but it can come with caveats depending on your database and settings.
From Laravel Docs
Using Multiple Database Connections
You may access each connection via the connection method on the DB facade when using multiple connections. The name passed to the connection method should correspond to one of the connections listed in your config/database.php configuration file:
$users = DB::connection('foo')->select(...);
You may also access the raw, underlying PDO instance using the getPdo method on a connection instance:
$pdo = DB::connection()->getPdo();
Useful Links
Laravel 5 multiple database connections FROM laracasts.com
Connect multiple databases in Laravel FROM tutsnare.com
Multiple DB Connections in Laravel FROM fideloper.com
In Laravel 5.1, you specify the connection:
$users = DB::connection('foo')->select(...);
Default, Laravel uses the default connection. It is simple, isn't it?
Read more here: http://laravel.com/docs/5.1/database#accessing-connections
Actually, DB::connection('name')->select(..) doesnt work for me, because 'name' has to be in double quotes: "name"
Still, the select query is executed on my default connection. Still trying to figure out, how to convince Laravel to work the way it is intended: change the connection.
Edit: I figured it out. After debugging Laravels DatabaseManager it turned out my database.php (config file) (inside $this->app) was wrong. In the section "connections" I had stuff like "database" with values of the one i copied it from. In clear terms, instead of
env('DB_DATABASE', 'name')
I needed to place something like
'myNewName'
since all connections were listed with the same values for the database, username, password, etc. which of course makes little sense if I want to access at least another database name
Therefore, every time I wanted to select something from another database I always ended up in my default database
Laravel has inbuilt support for multiple database systems, you need to provide connection details in config/database.php file
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
'mysqlOne' => [
'driver' => 'mysql',
'host' => env('DB_HOST_ONE', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE_ONE', 'forge'),
'username' => env('DB_USERNAME_ONE', 'forge'),
'password' => env('DB_PASSWORD_ONE', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
];
Once you have this you can create two base model class for each connection and define the connection name in those models
//BaseModel.php
protected $connection = 'mysql';
//BaseModelOne.php
protected $connection = 'mysqlOne';
You can extend these models to create more models for tables in each DB.
Also you can use postgres fdw system
https://www.postgresql.org/docs/9.5/postgres-fdw.html
You will be able to connect different db in postgres. After that, in one query, you can access tables that are in different databases.
This worked for me
The Middleware:
<?php
namespace App\Http\Middleware;
use Config;
use Closure;
use DB;
class DBSelect
{
public function handle($request, Closure $next)
{
//$db_name = "db1";
$db_name = "db2";
Config::set('database.connections.mysql.database', $db_name);
DB::reconnect('mysql');
return $next($request);
}
}
global Kernel.php
protected $middleware = [
.....
\App\Http\Middleware\DBSelect::class,
];
I changed some code from this answer (https://stackoverflow.com/a/64744187/4514022) and it worked for me.
Not a good solution if you want to clone the existing system and to run the existing code on a new database for a new customer.
We would have to edit hundreds of eloquent calls to insert the DB::connection('foo')
In CakePHP 3.0, what's the equivalent of calling getDataSource() from inside a controller (like $this->ModelName->getDataSource()in cakephp 2.x)?
I have tried this:
use Cake\Datasource\ConnectionManager;
$conn = ConnectionManager::get('my_connection');
Since this connection is connected already, why do I need to provide 'my_connection'?
How can I can get the DataSource from inside a Controller in CakePHP 3.0?
Thanks
Database\ConnectionManager::get() has been added. It replaces getDataSource()
CakePHP Cookbook 3
Begin, commit and rollback are now functions on the connection, not the data source. Use $conn = ConnectionManager::get($connectionName) and then use $conn->begin(), $conn->commit() and $conn->rollback().
http://book.cakephp.org/3.0/en/orm/database-basics.html#using-transactions
And use $this->Table->defaultConnectionName() to get the connection name to pass to get.
"my_connection" should be defined in cakephp 3 config
.go to cakephp/config/app.php
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
/**
* CakePHP will use the default DB port based on the driver selected
* MySQL on MAMP uses port 8889, MAMP users will want to uncomment
* the following line and set the port accordingly
*/
//'port' => 'non_standard_port_number',
'username' => 'root',
'password' => '',
'database' => 'cake',
'encoding' => 'utf8',
'timezone' => 'UTC',
'flags' => [],
'cacheMetadata' => true,
'log' => false,
connection name is "default" for this case.
Each Model that used in controller have one Connection.
You can get connection in controller from model by this method.
$model=TableRegistry::get('table_name');
$connection = $model->connection();