【问题标题】:Laravel 5.1 No query results for model in queueLaravel 5.1没有队列中模型的查询结果
【发布时间】:2015-10-07 05:59:48
【问题描述】:

我正在尝试从其官方文档中学习 laravel 数据库队列。我已经完成了文档中给出的配置。

这是我的工作:

<?php

namespace App\Jobs;

use App\SearchLog;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendTicket extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $log;

    protected $searchLog = array();



    public function __construct(SearchLog $log , $data = array())
    {
        $this->log = $log;
        $this->searchLog = $data;
    }

     /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

      $this->log->create($this->searchLog);     
    }

在我的控制器中我这样调用

public function store(Request $request)
{
 $searchLog = array();
 // searchLog contains the data to be inserted into database 
 $log = new SearchLog();
 $this->dispatch(new SendTicket($log , $searchLog));
 }

当我运行 php artisan queue:listen 时,我收到类似

的错误

[Illuminate\Database\Eloquent\ModelNotFoundException] 无查询 模型 [App\SearchLog] 的结果。

但是当我像这样编辑工作时

//only edited code 
public function __construct($data = array())
{
    $this->searchLog = $data;
}

/**
 * Execute the job.
 *
 * @return void
 */
public function handle()
{
  SearchLog::create($this->searchLog);   
}

当这样打电话时

 public function store(Request $request)
 {
    $searchLog = array();
    // searchLog contains the data to be inserted into database 
    $this->dispatch(new SendTicket($searchLog));
 }

它工作正常,数据已插入。
在这里,我的问题是:

  1. 如何将对象发送到队列中?
  2. 将数据发送到队列以便我们进行处理的最佳方式是什么?

【问题讨论】:

标签: php laravel laravel-5.1


【解决方案1】:

问题出在use Illuminate\Queue\SerializesModels; 中,它试图序列化您传递给构造函数的SearchLog $log 参数。由于您的模型尚未保存,因此它没有标识符。

根据 Laravel 文档:

如果您的队列作业在其构造函数中接受 Eloquent 模型,则仅 模型的标识符将被序列化到队列中。什么时候 作业被实际处理,队列系统会自动 从数据库中重新检索完整的模型实例。

解决方法是从您愿意保存模型的 Job 类中删除 SerializesModels 特征。

【讨论】:

  • stackoverflow.com/a/42981667/470749 是一个对我有帮助的相关问题。
  • @Ryan 嗨,Ryan,请帮助我理解“只有模型的标识符会被序列化”。我还不清楚。即使我将模型实例传递给 Job 构造函数。虽然,它在大多数情况下都能正常工作。有时它会抛出“没有模型查询结果”。我相信我的问题的解决方案就在你所说的某个地方。
  • @ronen 感谢您指出这一点。有同样的问题。我的查询有一个 group by 并且不包括主键,所以我必须只选择外键(按外键分组)并遇到这个问题。我删除了邮件类和 bam 中的序列化!它有效。
  • @Ronen 尝试删除 SerializesModels 特征并且效果很好。但是根据您在文档中的引用,我意识到当我从数据库中获取数据时,我没有得到id 字段的结果。因此,我将id 添加到Eloquent 对象,它也起作用了。
  • 是的,“模型的标识符”是要存储的。默认情况下,Laravel 使用 $id 字段作为模型的主键。即使您可以覆盖它。有时人们喜欢使用 uuid 来代替。你可以在这里阅读更多信息:laravel.com/docs/eloquent#primary-keys
【解决方案2】:

我遇到了同样的问题。

如果您想将模型推送到队列中,似乎只有它的 ID 会保存在有效负载中。因此,如果您还没有保存模型,它在处理程序中将不可用。

毕竟我是在队列和 Eloquent 模型部分的 documentation 中找到的。

为了解决这个问题,我看到了两个解决方案,第一个是确保你有一个持久模型:

public function store(Request $request)
{
 $searchLog = array();
 // searchLog contains the data to be inserted into database 
 $log = new SearchLog();
 //Save the Searchlog beforehand if it doesn't have any data constraints
 $log->save();
 //Dispatch the Job with the saved Model
 $this->dispatch(new SendTicket($log , $searchLog));
 }

仅将完整的模型保存过程放入处理程序,就像您在示例中所做的那样。

//Full saving/initializing is happening here
public function handle()
{
  SearchLog::create($this->searchLog);   
}

在我的情况下,我必须在高性能进程中将模型保存到数据库中,所以我将它完全放入处理程序中,我的进程不依赖于数据库保存速度。所以我会把它放在 handle() 函数中。

【讨论】:

    【解决方案3】:

    如果模型尚未保存或持久化,通常会引发此问题。检查您的模型实例和持久性。另一个可能引发此问题的事情是多租户。因此,如果您正在使用或构建具有多数据库的多租户应用程序,您可能需要想办法将数据库连接传递给队列,或者只使用 Tylor Otwell 在此处 [5.4] Support queued jobs with unpersisted models

    所述的数据数组

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2019-12-04
      • 1970-01-01
      相关资源
      最近更新 更多