Laravel-excel: [質問]インポートイベント後

作成日 2018年12月07日  ·  24コメント  ·  ソース: Maatwebsite/Laravel-Excel

前提条件

バージョン

  • PHPバージョン:7.2
  • Laravelバージョン:5.7
  • パッケージバージョン:3.1

説明

インポート後のイベントを機能させるのに問題があります。 イベントは発生しません。 :(
アフターシートは正常に機能しますが、何が間違っていますか?

登録イベントと自動登録イベントの両方を試しました。

私のコード

namespace App\Imports;

use App\Order;
use App\Order\Address;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Events\AfterImport;
use Maatwebsite\Excel\Events\BeforeImport;

class OrderAddressImport implements
    WithHeadingRow,
    ToModel,
    WithBatchInserts,
    WithChunkReading,
    WithCustomCsvSettings,
    ShouldQueue,
    WithEvents
{
    use Importable, RegistersEventListeners;

    protected $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * <strong i="16">@param</strong> array $row
     * <strong i="17">@return</strong> Address
     */
    public function model(array $row)
    {
        $data = ['order_id' => $this->order->id];
        $data = array_merge($data, $row);

        return new Address($data);
    }


    public function batchSize() : int
    {
        return 1000;
    }

    public function chunkSize() : int
    {
        return 5000;
    }

    /**
     * <strong i="18">@return</strong> array
     */
    public function getCsvSettings(): array
    {
        return [
            'delimiter' => ';',
            'enclosure' => '',
            'input_encoding' => 'UTF-8'
        ];
    }

    public static function afterImport(AfterImport $event)
    {
       dd($event);
    }
}
bug

最も参考になるコメント

次のリリース(現在は3.1-dev)では、チャンク読み取りのBefore / AfterImportイベントがサポートされる予定です。 また、チャンクジョブのいずれかが失敗したときに発生するImportFailedイベントを追加します。 (https://twitter.com/patrickbrouwers/status/1114166252711415808)

3.1ブランチで自由にテストして、例外のように機能するかどうかを知らせてください。

全てのコメント24件

同じ問題があります。 WithChunkReadingコントラクトを実装している場合、 AfterImportイベントは発生しないようです。

これは、BeforeImportイベントにも当てはまるようです

コードをざっと見てみましたが、ChunkReaderクラスでこのイベントを発生させるコードはまったく見つかりませんでした。

そして、私がそれについて考えるとき、これに対する良い解決策はありません。 たぶん1つの解決策は、afterImportメソッドを上げるためにチェーンに単一のジョブを追加することかもしれませんか?

このトピックに対する答えはありますか? :)

はい、これをバグとして特定しました。 将来のバージョンでその解決策を考え出すことができるかどうかを確認します。

@GlennMこれと言えば、BeforeChunkイベントとAfterChunkイベントも実装して、進行状況のフロントエンドGUIを更新できるようにする方法があるかどうかを確認したいと思います...これで考慮すべきこと、合計数+合計チャンク+現在のチャンク(考えのためだけに)である必要があります。私のファイルのほとんどはGUIを介して実行されますが、かなり大きいので、何らかの「進行中」を与えることができる方が、不確定よりも優れています。プログレスバー

BeforeChunkとAfterChunkのサウンドが可能です。

BeforeImport / AfterImportはもっと注意が必要です。 それらを2つの追加ジョブとしてチェーンに追加すると、ファイルが2倍開かれるため、パフォーマンスに影響があります。 最良のオプションは、最初のジョブでbeforeimportを実行し、最後のジョブでafterimportを実行することだけです。 それが可能かどうかを確認します。

チャンクジョブにBeforeImport / AfterImportイベントを追加するための+1。 これらを2つのジョブとしてチェーンに追加する提案を提出しようとしていましたが、すでに参加しているようです。 最初と最後のジョブにイベントを実装するというあなたの提案も、可能であれば最もよく聞こえます。

AfterImportは、ShouldQueueおよびWithChunkReadingでは機能しません。
また、キューに必要なため、キュー実行終了時のイベントは実装されていません。

ドキュメントの提案で:

$ import-> queue( 'users.xlsx')-> chain([
new NotifyUserOfCompletedImport(request()-> user())、
]);

各キューアイテムが起動されます:NotifyUserOfCompletedImport

Algumasugestão?

私は同じ問題に遭遇しました。 これを解決するには、ShouldQueueを実装するジョブを作成し、そこからインポートを実行して、インポートの終了後に必要なアクションを実行します(それ以外の場合はafterImportイベントで実行されます)。 インポートはバッチ挿入とチャンク読み取りを構成し、ジョブで同期的に実行されます。

上記の利点の1つは、どのキューワーカーがジョブを実行しているかを簡単に制御できることです。

もう1つの(非常に重要な)利点は、キューに入れられたジョブでXLSファイルをインポートできることです。 Importクラス自体にShouldQueueを実装する標準的なアプローチを使用する場合は不可能なこと。

私は同じ質問をします。

私はこのロジックと私の問題を解決し@patrickbrouwersから更新されたドキュメントでzxl2006001 @。

(new UsersImport)->queue('users.xlsx')->chain([
    new NotifyUserOfCompletedImport(request()->user()),
]); 

ここを参照してください: https ://docs.laravel-excel.com/3.1/imports/queued.html#appending -jobs

現在の設計には、実際にはさらに2つの結果があります。

  1. Readerクラスのreadメソッドを見ると、ChunkReaderの読み取りが呼び出される前に同期的に起動されるのではなく、beforeImportがbeforeReading内でのみ起動される理由は明らかではありません。

  2. チャンク化されたシナリオでは、ジョブをチェーンして通知処理を実行できますが、「currentFile」プロパティが保護されているため、一時ファイルの適切なクリーンアップを実行できず、自動的に実行されません。一時的なクリーンアップ。

失敗したインポートを処理するための回避策はありますか? 私が現在考えることができる唯一の方法は、laravelsグローバルジョブエラーイベントを使用することです。

それに関する問題は、私がaatwebsiteExcel \ Jobs \ ReadChunkプロセスを制御できないことです。 これは、失敗したジョブについて必要なデータをグローバルイベントに渡すことができないことを意味します。

chunkSizeを使用するときにエラーを処理するにはどうすればよいですか?

次のリリース(現在は3.1-dev)では、チャンク読み取りのBefore / AfterImportイベントがサポートされる予定です。 また、チャンクジョブのいずれかが失敗したときに発生するImportFailedイベントを追加します。 (https://twitter.com/patrickbrouwers/status/1114166252711415808)

3.1ブランチで自由にテストして、例外のように機能するかどうかを知らせてください。

インポートにdatabaseキュードライバーを使用し、インポートクラスにWithChunkReadingを実装すると、 AfterImportイベントを複数回トリガーするようになります。 それは予想される動作ですか?

databaseキュードライバーとバージョン3.1 、インポートが成功するたびにAfterImportが2回トリガーされるのを経験しています。

databaseキュードライバーとバージョン3.1でもインポートが成功した後、 AfterImportが無期限にトリガーされるのを経験しています

インポートにredisキュードライバーを使用し、インポートクラスにWithChunkReadingを実装すると、 AfterImportイベントが複数回トリガーされます。 それは予想される動作ですか?

エラーログは次のとおりです。

local.ERROR: unlink(/Users/sineld/Code/project/public/uploads/tmp/laravel-excel-qfK6O5aCHxhFXioVayQbLQag5UnFKyxB.xlsx): No such file or directory {"exception":"[object] (ErrorException(code: 0):

同じ彼女のAfterImportが2回呼び出されます。

また、AfterImportリスナーが2回呼び出されていることに遭遇しています。 xdebugでデバッグした後、リスナーが2つの場所に登録されていることがわかりました。

次のリリースで修正

このページは役に立ちましたか?
0 / 5 - 0 評価