Laravel where() 和 orderBy() 在外部服务器上的关系表上

Posted

技术标签:

【中文标题】Laravel where() 和 orderBy() 在外部服务器上的关系表上【英文标题】:Laravel where() and orderBy() on a relation table that's on an external server 【发布时间】:2020-03-22 22:49:13 【问题描述】:

我需要使用 Laravel where()orderBy() 方法。问题是我需要过滤和排序的数据来自外部服务器/另一个主机数据库(PostgreSQL)上的关系

我尝试过的:

public function index(Request $request)
    
        $productforms = $this->productform
            ->select('product_forms.*')
            ->with('product')
            ->join('types', 'product_forms.type_id', '=', 'types.id')
            ->where('product.description', 'ILIKE', '%sugar%');
            // ...
    

也试过了:

$rawquery = DB::table('product_forms')
    ->join('testing.base.products as db2','product_forms.product_id','=','db2.id')
    ->select(DB::raw('form_title as title'))
    ->first();

我搜索了很多主题,但没有找到完全相似的内容。

上述第二次尝试的 Laravel 错误消息:

"""
SQLSTATE[0A000]: Feature not supported: 7 ERROR:  cross-database references are not implemented: "testing.base.product"
LINE 1: ...m_title as titulo from "product_forms" inner join "test...
                                                             ^ (SQL: select form_title as titulo from "product_forms" inner join "testing"."base"."product ▶
"""

上述第一次尝试的 Laravel 错误消息:

"""
SQLSTATE[42P01]: Undefined table: 7 ERROR:  missing FROM-clause entry for table "products"
LINE 1: ...on "product_forms"."type_id" = "types"."id" where "products"...
                                                             ^ (SQL: select "product_forms".* from "product_forms" inner join "types" on "product_forms"."type_id" = "types"."id" where "products"."description"::text ILIKE %sugar%) ◀
"""

本地服务器模型productForm:

class ProductForm extends Model implements Auditable


    protected $table='product_forms';

    protected $connection = 'localserver';

    protected $fillable = [
        'id', 
        'product_id', 
        'type_id'
        // ...
    ];

    public function product()
        return $this->belongsTo(Product::class);
    


外部服务器模型产品:

class Product extends Model


    protected $connection='externalserver';

    protected $table='base.products';

    protected $fillable = [
       'id',
       'description',
       'attributes'
       // ...
    ];
    // ...


示例环境结构:

DB_CONNECTION=localserver
DB_HOST_PG=127.0.0.1
DB_PORT_PG=5432

DB_CONNECTIONK=externalserver
DB_HOST_PGK=externaldomain.com
DB_PORT_PGK=5432

Conf/database.php 连接:

'connections' => [

    'localserver' => [
        'read' => [
            'host' => env('DB_HOST_PG', '127.0.0.1'),
        ],
        'write' => [
            'host' => env('DB_HOST_PG_WRITE', '127.0.0.1'),
        ],
        'driver' => 'pgsql',
        'port' => env('DB_PORT_PG', '5432'),
        // ...
    ],

    'externalserver' => [
        'driver' => 'pgsql',
        'host' => env('DB_HOST_PGK', 'externaldomain.com'),
        'port' => env('DB_PORT_PGK', '5432'),
        // ...
    ]

]

谢谢!任何提示都会帮助我

【问题讨论】:

您说发生了问题,但您并没有真正描述实际发生的情况。您是否收到错误消息?崩溃?你能做更多不涉及whereorderBy的简单查询吗? 你试过 Laravel 的查询构建器了吗?您可以在它自己的构建器中指定连接名称。看看这个,可能会有所帮助:***.com/questions/27955700/… 您试图连接不同数据库中的两个表?如果您尝试这样做,则需要在主数据库上复制您尝试执行的表 where 和 orderBy。 你为什么要创建模型只使用外部数据库的原始查询,因为你将无法与它创建任何关系! 对不起,忘记了消息错误,我已经编辑了问题并且也有以下问题:“”“SQLSTATE [42P01]:未定义的表:7 错误:缺少表“产品的FROM子句条目” " LINE 1: ...on "product_forms"."type_id" = "types"."id" where "products"... ^ (SQL: select "product_forms".* from "product_forms" 内部连接 ​​"types" on "product_forms"."type_id" = "types"."id" where "products"."description"::text ILIKE %sugar%) ◀ """ @Spudley 谢谢 【参考方案1】:

我认为这还不是更好的解决方案,但我暂时找到了解决方法。我的目标是使用 where() 为列表创建搜索过滤器。我提出的解决方法是:

在模型上,使用条件局部范围:

public function scopeSearchField($query, $search) 

        // retrieving the external cross-database data using where() on a closure inside eager loading/with() method

        if (!empty($search['product']) ) 
            $query->with(
                    [
                        'product' =>
                            function ($query) use($search)
                                $query->whereRaw(" public.unaccent('description')::text ILIKE public.unaccent('%$search["product"]%')::text");
                            
                    ]);
        

    

在控制器上:

$productforms = $this->productform
    ->select('product_forms.*')
    ->searchField($request->all());

在观点上:

@forelse($productforms as $productform)
                @if($productform->product!= null)

                <tr>
                    <td>$productforms->title</td>
                    <td>$productforms->product->description</td>
                    <td>$productforms->...</td>
                    <td>$productforms->...</td>
                </tr>

                @endif
@endforelse

【讨论】:

以上是关于Laravel where() 和 orderBy() 在外部服务器上的关系表上的主要内容,如果未能解决你的问题,请参考以下文章

根据用户表[laravel]中的列使用orderBy()订购产品表

Laravel orderBy和groupBy with if statement

Laravel 5 - 多维 groupBy、orderBy 和 paginate

laravel框架orderBy问题

laravel如何打印orm封装的sql语句

Laravel orderBy 与列值