如何覆盖Laravel的数据库连接 [英] How to overwrite Laravel's database connection

查看:281
本文介绍了如何覆盖Laravel的数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Folks,



我一直在试图克服这个问题超过10个小时,我决定在疯狂之前寻求帮助。 p>

我想要实现的是一些排序多租户,我为每个客户提供一个专用数据库,并且根据具体数据库的加载请求。例如。如果客户A发送请求,则加载数据库A,如果B发送请求,则加载数据库B.我们有成千上万的客户,因此在databse.php文件中预定义所有配置是不可选的。



在一些特殊情况下,不管发行者如何,都应该加载相同的数据库。例如。如果请求是X,总是加载数据库C.



我有以下架构:
扩展雄辩模型的BaseModel。
扩展BaseModel的应用程序模型。
与应用程序模型对话的几个库。



由于我的所有数据库请求都通过BaseModel,所以我认为最有效的解决方案是插入在BaseModel的构造函数中切换到正确数据库的代码。例如:

  class BaseModel extends \Eloquent {


public function __construct $ attributes = array()){

$ currentConfigs = \Config :: get('database.connections.customers');

$ currentConfigs ['database'] ='db_A'; //这取决于请求
$ currentConfigs ['prefix'] ='custName'; //这取决于请求

\Config :: set('database.connections.customers',$ currentConfigs);

parent :: __ construct($ attributes);
}

我所面临的问题是我似乎可以设置只配置一次。换句话说,如果我在请求的整个生命周期中只需要数据库A或B,则所有工作都可以正常工作。虽然如果我需要切换到数据库C,这不行。即使我试图显式地加载C,BaseModel仍然继续寻找A或B中的所需表。看起来好像数据库设置是不可变的或类似的。



这就是说,我有几个问题:


  1. 什么是动态加载不同数据库运行时的最佳方法,请注意,一个请求可能需要查询多个数据库,而不仅仅是一个。


  2. 如何我卸载或重置数据库连接,以便我设置一个新的?


  3. Laravel中的哪个方法可以提供有关当前数据库连接的信息?我需要调试的方法,但我完全不了解可能的方法。


任何帮助/提示将不胜感激。

解决方案

问题是,Laravel使用配置建立连接,然后将其保存在内存中。如果要通过设置新的连接变量来实现,则必须在进行更改后重新连接。 (还要注意,你可以直接用awesome点符号设置配置)

  \Config :: set('database。 connections.customers.database','db_A'); 
DB :: reconnect('customers');

但是,在我看来,更好的方法是使用SQL来切换数据库

  DB :: unprepared('USE db_A'); 

要获取当前数据库名称,您还可以使用SQL

  DB :: select('SELECT DATABASE()')[0]  - > {DATABASE()} // DATABASE()你不使用MySQL 



更新 - 表前缀



一个简单的方法来使表前缀动态,将在BaseModel构造函数中添加此元素

  $ this - >硬性( 'CUSTNAME' $这 - > getTable()); 


Folks,

I've been trying to overcome this issue for more than 10 hours now and I've decided to look for help before going insane.

What I'm trying to achieve is some sort multi-tenancy where I have a dedicated database for each customer and depending on the issuer of the request the concrete database should be loaded. E.g. if customer A sends a request, load database A, if B sends the request, load database B. We have thousands of customers, so having all configs predefined in the databse.php file is not an option.

In a few special cases, the same database should be loaded irrespective of the issuer. E.g. if the request is X, always load database C.

I have the following architecture: BaseModel which Extends Eloquent Model. Application models which extend BaseModel. A few libraries which talk to the Application models.

Since all my database requests go through BaseModel, the best solution that I thought would work was to insert the code which switches to the correct database in the BaseModel's constructor. E.g.:

class BaseModel extends \Eloquent { 


public function __construct(array $attributes = array()) {     

    $currentConfigs = \Config::get('database.connections.customers');    

    $currentConfigs['database'] = 'db_A'; //this varies depending on the request
    $currentConfigs['prefix'] = 'custName'; //this varies depending on the request                               

    \Config::set('database.connections.customers', $currentConfigs); 

    parent::__construct($attributes);        
} 

The problem that I am facing is that I seem to be able to set the configs only once. In other words, if I only need database A or B throughout the lifecycle of the request, all works fine. Though, if I need to switch to database C, this doesn't work. BaseModel continues to look for the required tables in A or B, even though I tried to explicitly load C. It looks as if the db settings are immutable or something like that.

That said, I have a few questions:

  1. What is the best way to dynamically load different databases run-time, having in mind that one request may need to query multiple databases and not just one.

  2. How can I unload or reset the database connection, so that I set a new one?

  3. Which method in Laravel can give me information about the current db connection? I need ways to debug this, but I'm totally blind to the possible ways to go about that.

Any help/tips would be appreciated.

解决方案

The problem is, that Laravel establishes a connection using the config and then keeps it in memory. If you want to do it by setting new connection variables, you have to reconnect after making changes. (also note that you can set the config directly with the awesome dot notation)

\Config::set('database.connections.customers.database', 'db_A');
DB::reconnect('customers');

However the better way, in my opinion, is to just use SQL to switch the database

DB::unprepared('USE db_A');

To get the current database name you can use SQL as well

DB::select('SELECT DATABASE()')[0]->{"DATABASE()"} // DATABASE() might be something else if you're not using MySQL

Update - Table prefix

An easy way to make the table prefix dynamic too, would be to add this in your BaseModel constructor

$this->setTable('custName'.$this->getTable());

这篇关于如何覆盖Laravel的数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆