CSVファイルからデータを読み取るスクリプトを作成し、データがデータベースに既に存在するかどうかをチェックし、そうでない場合はインポートします。データが存在する場合(特定の製品のコード)、残りの情報はCSVファイルから更新する必要があります。CSVからデータベースに存在しないデータのみをインポートする
たとえば、 CSVファイルにAlexという名前とJohnsonという名前のコードWTW-2LTのメンバーがあります。このスクリプトは、WTW-2LTというコードのAlexとJohnsonという名前のメンバーが既に存在するかどうかをチェックし、連絡先の詳細と追加の詳細をスクリプトから更新する必要があるかどうかを確認します(件名や講師、すべての詳細がCSVの1行にあります)、存在しなければ新規メンバーを作成するだけです。
私のスクリプト今のところ気を散らすことを防ぐために最小限のチェックを行っています。
while ($row = fgetcsv($fp, null, ";")) {
if ($header === null) {
$header = $row;
continue;
}
$record = array_combine($header, $row);
$member = $this->em->getRepository(Member::class)->findOneBy([
'code' =>$record['member_code'],
'name' =>$record['name'],
'surname' =>$record['surname'],
]);
if (!$member) {
$member = new Member();
$member->setCode($record['member_code']);
$member->setName($record['name']);
$member->setName($record['surname']);
}
$member->setContactNumber($record['phone']);
$member->setAddress($record['address']);
$member->setEmail($record['email']);
$subject = $this->em->getRepository(Subject::class)->findOneBy([
'subject_code' => $record['subj_code']
]);
if (!$subject) {
$subject = new Subject();
$subject->setCode($record['subj_code']);
}
$subject->setTitle($record['subj_title']);
$subject->setDescription($record['subj_desc']);
$subject->setLocation($record['subj_loc']);
$lecturer = $this->em->getRepository(Lecturer::class)->findOneBy([
'subject' => $subject,
'name' => $record['lec_name'],
'code' => $record['lec_code'],
]);
if (!$lecturer) {
$lecturer = new Lecturer();
$lecturer->setSubject($subject);
$lecturer->setName($record['lec_name']);
$lecturer->setCode($record['lec_code']);
}
$lecturer->setEmail($record['lec_email']);
$lecturer->setContactNumber($record['lec_phone']);
$member->setLecturer($lecturer);
$validationErrors = $this->validator->validate($member);
if (!count($validationErrors)) {
$this->em->persist($member);
$this->em->flush();
} else {
// ...
}
}
このスクリプトは、データベースに3回問い合わせて1つのCSV行が存在するかどうかを確認する必要があることがわかります。私の場合は、最大2000行以上のファイルがあるので、すべての行が3行のクエリを実行してその行が存在するかどうかを確認するのはかなり時間がかかります。
残念ながら、1つのサブジェクトが存在しない場合は、バッチがデータベースにフラッシュされ、ポイントを持たない重複レコードがあるまで何度も作成されるため、バッチでローをインポートすることもできません。
パフォーマンスとスピードを最大限に向上させるにはどうすればよいですか?最初にデータベースからすべてのレコードを取得し、配列に格納して(メモリを消費しますか?)、チェックを行い、配列に行を追加してそこからチェックします。
うーん、OK、私は私の推測タイムアウトは主に問題であるため、 'set_time_limit'の使用に慣れる必要があります。 – Mentos93
制限時間を変更しない場合は、行を個々のSQLクエリに変換するスクリプトを作成できます。クエリーをtxtファイルとして保存してサーバーにアップロードするよりも、 phpでは、ファイルからX行を読み込み、データベース上でそれらを実行し、最後に実行した行を保存することができます。次回以降はその行から続行します。しかし、このようにするにはさらに多くの作業が必要ですが、サーバー負荷のバランスをさらに取ることになります。 – Jeffrey