Laravel在两个独立的数据库中

时间:2014-12-10 06:35:59

标签: php laravel laravel-4 eloquent relationship

问题:如果客户已经下了当年的订单,我想要获得客户。客户和订单位于两个单独的数据库中(这无法更改)。这些关系都设置正常并且工作正常但是当我尝试以下操作时,我不断收到SQL错误,因为它正在尝试搜索' orders'在'客户'数据库。反正是否有强制Laravel在这种情况下使用正确的数据库?

$customers = $customers->whereHas('orders', function($query){
    $query->where('academic_year_id', '=', $this->current_academic_year->id);
});

$customers = $customers->orderBy('DFKEY','ASC')->get();

订单型号:

public function customer()
{
    return $this->belongsTo('Customer','dfkey');
}

客户模式:

protected $connection = 'mysql2';

public function orders()
{
    return $this->hasMany('Order','dfkey','DFKEY');
}

提前致谢!

8 个答案:

答案 0 :(得分:1)

晚会但对于有类似问题的任何其他人,以下应该可以工作(只要两个数据库都在一个服务器上)。

明确设置连接和表。

protected $connection = 'mysql2';
protected $table_name = 'mysql2.orders';

或者如果你想 - 像这样动态设置表格:

protected $table = 'orders';
public function __construct() {
    $this->table = DB::connection($this->connection)->getDatabaseName() . '.' . $this->table_name;
}

甚至

public function __construct() {
    $this->table = DB::connection($this->connection)->getDatabaseName() . '.' . $this->getTable();
}

答案 1 :(得分:0)

尝试编写这样的查询,并将您的数据库和表名设置为>

$customers = Schema::connection('your_database_name')::table('respective_table_name')
->where('academic_year_id', '=', $this->current_academic_year->id)
->orderBy('DFKEY','ASC')
->get();

答案 2 :(得分:0)

使用过滤器解决了这个问题:

public function index()
{   
    $customers = new Customer;
    // Make sure customers are current parents of students
    $customers = $customers->whereHas('students', function($q) {
        $q->where('STATUS', '=', 'FULL');
    });

    //Filter results
    if(Input::get('academic_year') == 'ordered'){
        $customers = $customers->orderBy('DFKEY','ASC')->get();
        $filtered = $customers->filter(function($customer)
        {
            if ($customer->orders()->where('academic_year_id','=',$this->current_academic_year->id)->first()) {
                return true;
            }
        });
        $customers = $filtered;
        return View::make('admin.customers.index',compact('customers'));
    }

    $customers = $customers->orderBy('DFKEY','ASC')->get();

    return View::make('admin.customers.index',compact('customers'));
}

答案 3 :(得分:0)

我已经通过添加“连接”和“表”变量模型来解决此问题,这些模型指定了保存数据库的特定数据库。

例如,我在表users中的名为“ core_database”的数据库中有一个名为“ User”的模型。 另一方面,我在表“ user_events”中名为“ logs_database”的数据库中有一个名为“ UserEvents”的模型

所以我将在config / database.php文件上有两个部分:

'core_db_connection' => [
        'driver' => 'mysql',
        'host' => host_ip,
        'port' => port,
        'database' => 'core_database',
        'username' => username,
        'password' => password,
        ....
    ],

'logs_db_connection' => [
        'driver' => 'mysql',
        'host' => host_ip,
        'port' => port,
        'database' => 'logs_database',
        'username' => username,
        'password' => password,
        ....
    ],

模型将是:

class User extends Authenticatable {
  protected $table = 'core_database.users';
  protected $connection = 'core_db_connection';
  ...
}

class UserEvents extends Model {
  protected $table = 'logs_database.user_events';
  protected $connection = 'logs_db_connection';
  ...
}

使用此配置,我可以在两个或多个分离的数据库中进行任何查询。 希望对您有帮助!

答案 4 :(得分:0)

https://github.com/laravel/framework/issues/24398#issuecomment-511891818
它对我来说很好,但是两个数据库都应该在同一服务器上

答案 5 :(得分:0)

没有多余的方法,但是您可以分两步完成,这与Laravel正常执行的方法相同。

它简单,干净,有效,您也不会混淆可能在更新时更改的Laravel核心功能

    $orders = Order::where('academic_year_id', $this->current_academic_year->id)
                     ->select('id')
                     ->pluck('id');


    $customers = $customers->whereIn('order_id', $orders)
                           ->orderBy('DFKEY','ASC')
                           ->get();

希望这对您有用。

P.D .:您可以在其中跳过等号

答案 6 :(得分:0)

hoyvoy/laravel-cross-database-subqueries 包允许您为同一服务器中的数据库执行此操作。您还需要指定 Agus Trombotto 指定的所有数据库连接和与其相关的模型。最后,引用另一个数据库的模型必须从 Hoyvoy\CrossDatabase\Eloquent\Model 而不是 Illuminate\Database\Eloquent\Model 扩展。

答案 7 :(得分:0)

这其实是一个很好的问题! 直接在该模型上进行简单查询不会有问题,因为 Laravel 使用来自模型的默认连接,但是如果您在另一个数据库中有相关模型并且您执行一些高级查询,例如:whereHas('relationName'),Laravel 将使用parent 的连接会导致关于不存在列的 SQL 错误(因为它在错误的数据库中查找)。

这是此问题的最佳解决方案:

在你的相关模型中创建一个像这样的构造函数:

public function __construct(array $attributes = [])
{
    $this->table = 'db_name.'.$this->table;
    parent::__construct();
}