Как я могу проверить, существует ли номер телефона в БД во время импорта файла?

avatar
user6085744
9 августа 2021 в 03:58
134
2
0

Я хочу проверить, существует ли телефон в базе данных. Если он существует, строку следует пропустить. Могу ли я сделать это без вызова базы данных каждый раз?

namespace App\Imports;

use App\Models\Friend;
use App\Traits\UniqueId;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class FriendsImport implements ToModel, WithBatchInserts, WithHeadingRow
{
    use UniqueId;

    public function model(array $row)
    {
        return new Friend([
            'phone' => $row['phone'],
            'postcode' => $row['postcode'],
            'user_id' => Auth::user()->id,
            'unique_id' => $this->generateUniqueNumber(),
        ]);
    }

    public function headingRow(): int
    {
        return 1;
    }

    public function batchSize(): int
    {
        return 100;
    }
}
Источник
matiaslauriti
9 августа 2021 в 04:32
0

Есть много способов "решить" то, что вы хотите, это не значит, что эти способы эффективны... Один из них - хранить числа в cache, например redis, чтобы он был доступен супер быстро (это было бы лучшим). Другой процесс должен отправить файл job (асинхронно) и позволить ему запрашивать номер построчно, а затем вызывать БД и удалять строку, если она существует. После завершения job отправьте его другому job, который будет обрабатывать добавление строк в вашу таблицу, потому что в файле уже нет существующих телефонов... Это действительно основано на мнении, так что...

TylerH
9 августа 2021 в 15:38
0

@matiaslauriti Конечно, есть много способов сделать это, но OP не спрашивает лучший способ, а только как это сделать. Это не делает этот вопрос основанным на мнении.

Ответы (2)

avatar
Saeed Nikookalam
9 августа 2021 в 04:53
1

Во-первых, вы можете сделать уникальные телефоны, прежде чем добавлять их в базу данных.

Или, Вы можете использовать красноречие, чтобы сделать это.

Можно использовать метод FirstOrCreate.

Этот метод вставляет новую запись, если идентификационный ключ не найден, иначе возвращает найденную строку.

Можно посмотреть: https://laravel.com/docs/8.x/eloquent#retrieving-or-creating-models

avatar
Alek Smith
9 августа 2021 в 04:34
1

Вы можете проверить так.

    $validator = Illuminate\Support\Facades\Validator::make($row,['phone'=>'require|unique:friends,phone']);
    if ($validator->passes()){
        // Phone number does not exist on the friends table.
    }else{
        // Phone number exist on the friends table.
    }

Если вы хотите проверить наличие в том же фрагменте (пакете), вам необходимо сохранить все данные пакета в статическом значении

нравится

// Import class

public static $chunkFriends = [];


// in them model function, for each row

array_push (self::chunkFriends, $row);

Затем вам нужно очистить $chunkFriends в событии чтения каждого блока.

public function registerEvents(): array
{
    return [
        ReadChunk::class=> function(){
            // put a code here
            self::chunkFriends = [];
        }
    ];
}

Другое решение — использовать драйвер сеанса или кэша.

user6085744
9 августа 2021 в 04:50
0

Получить ошибку после публичного статического chunkFriends = []; синтаксическая ошибка, неожиданное '=', ожидание переменной (T_VARIABLE)

Alek Smith
9 августа 2021 в 05:01
0

извините, я пропустил символ $. публичный статический $chunkFriends = [];