I am trying to get queued exports to work with the Laravel Excel package, but can’t figure out what I’m missing. I followed the docs on how to queue exports, but when I test it the export completes after the first batch is exported, so after the first 1000 rows. I setup my application to use the database driver in .env and generated/ran the migrations.
I’m using Laravel 5.8, Laravel Excel 3.1, PHP 7.2, Postgresql 10. Here’s a basic version of what I have so far:
Controller
public function export(Request $request){
$name = 'test.csv';
(new ExcelExport($client, $year))->queue('public/exports/' . $name)->chain([
new NotifyUserOfExport($request->user(), $name),
]);
return back()->with('message', 'This export will take some time. You will receive an email when it is ready to download.');
}
Export Class
class ExcelExport implements FromQuery, WithHeadings, WithMapping, WithStrictNullComparison
{
use Exportable;
public function __construct($client, $year)
{
$this->year = $year;
$this->client = $client;
}
public function query()
{
$query = $this->getQuery();
return $query;
}
public function headings(): array
{
//...
}
public function map($row): array
{
//....
}
private function getQuery()
{
return DB::table('mytable')
->where('year', $this->year)
->where('client', $this->client)
->orderBy('created_at')
->groupBy('column');
}
My queue.php
return [
'default' => env('QUEUE_CONNECTION', 'sync'),
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs', // also tried 'myschema.jobs'
'queue' => 'default',
'retry_after' => 90,
],
//.....
],
My .env
QUEUE_CONNECTION=database
I don’t think there’s any other code that’s relevant. I get the notification that’s supposed to send after all the jobs are finished, but like I mentioned earlier, it’s sent after the first batch is completed. There are no jobs inserted into the jobs table in the database either, so there’s the problem. I just can’t figure out what I’m missing.
I should mention that I don’t want to use the Implicit Export queueing, since this same export is used in another part of the application that only requires a few rows to be exported, so I don’t need to queue it.
Any help would be appreciated.
2
Answers
It turns out that because my query had a groupBy clause, I needed to implement a custom query size on the export class. I don't understand why that's an issue, but after I added that, the jobs were added to the queue and processed fine. So I added:
I hope this helps someone so they don't have to go through the headache I did.
Queued exportables are processed in chunks; each chunk being a job pushed to the queue by the QueuedWriter. In case of exportables that implement the FromQuery concern, the number of jobs is calculated by dividing the $query->count() by the chunk size.
#When to use
Depending on the implementation of the query() method (e.g. when using a groupBy clause), the calculation mentioned before might not be correct.
If this is the case, you should use the WithCustomQuerySize concern to provide a custom calculation of the query size.
Read more about here https://docs.laravel-excel.com/3.1/exports/queued.html#when-to-use