レコードを複数のデータベーステーブルにインポートするスクリプトが1つの親エンティティ(アドレス)に関連付けられています。CSVからのインポート、レコードがすでに存在しています。他の場合は成功しません。
アドレスが既に存在する場合は、追加の列はcsvに従って更新する必要があります。他のすべてのエンティティについても同じカウントです。カウンター($exist++
)を増やすか、配列($existingRecords
)を既存のレコードで埋める必要があります。
レコードで必須フィールドが空の場合、そのレコードを別の配列($failedRecords
)に追加するか、別のカウンタ($failed++
)を増やす必要があります。
アドレスがまだ存在せず、すべてのフィールドで作成する必要がある場合は、カウンタ($successful++
)だけを増やす必要があります。
最終的に私はユーザーのフィードバックのために、失敗した、成功した、そして既に存在する(しかし更新された)レコードの数を示す配列$result
を持っています。
私の現在のスクリプトをあまりにも邪魔することなく、すっきりとした方法でこれを実装するにはどうすればよいですか?現在レコードが存在する場合、レコードが既に存在する場合は$exist
カウンタが増加しますが、$successful
カウンタも増加します。レコードがすでに存在する場合は$exist
カウンタを増やし、レコードがまだ存在する場合は$successful
カウンタだけ増やします追加する必要があり、正常に追加されました。 $failed
カウンターでも同じです。ここで
(私が試したものと)私のスクリプトです:
public function import(CsvFile $csv) {
$root = __DIR__.'/../../../../../';
$file = $root.'var/data/'.$csv->getCsvName();
$fp = fopen($file, "r");
$batchSize = 25;
$header = null;
$successful = 0;
$failed = 0;
$exist = 0;
$results = [];
while ($row = fgetcsv($fp, null, ";")) {
if ($header === null) {
$header = $row;
continue;
}
$record = array_combine($header, $row);
// cast all values to correct data types
foreach ($record as $key => &$value) {
if (strpos($key, 'datum') !== false ||
strpos($key, 'tijdstip') !== false &&
strlen($value) == 8 &&
is_numeric($value)
) {
$value = \DateTime::createFromFormat('Ymd', $value);
}
if ($value === "") {
$value = null;
}
if (is_numeric($value)) {
intval($value) == $value ? $value = (int)$value : $value = (float)$value;
}
}
// required fields
if (!$record['name'] ||
!$record['surname'] ||
!$record['email'] ||
!$record['phone'] ||
!$record['street'] ||
!$record['houseNo'] ||
!$record['town'] ||
!$record['postcode'] ||
!$record['location'] ||
!$record['lecture'] ||
!$record['session'] ||
) {
$failed++;
continue;
}
$student = $this->em->getRepository(Student::class)->findStudent(
$record['name'], $record['surname'],
$record['email'], $record['phone']
);
if (!$student) {
$student = new Student();
$student->setName($record['name']);
$student->setSurname($record['surname']);
$student->setEmail($record['email']);
$student->setPhone($record['phone']);
} else {
$exist++;
}
$student->setAge($record['age']);
$student->setLength($record['length']);
$address = $this->em->getRepository(Address::class)->findOneBy([
'street' => $record['street'],
'houseNo' => $record['houseNo'],
'town' => $record['town'],
'postcode' => $record['postcode'],
);
if (!$address) {
$address = new Address();
$address->setStreet($record['street']);
$address->setHouseNo($record['houseNo']);
$address->setPostcode($record['postcode']);
$address->setTown($record['town']);
}
$student->setAddress($address);
$lecture = $this->em->getRepository(Lecture::class)->findOneBy([
'location' => $record['location'],
'lecture' => $record['lecture'],
'session' => $record['session'],
]);
if (!$lecture) {
$lecture = new Lecture();
$lecture->setLocation($record['location']);
$lecture->setLecture($record['lecture']);
$lecture->setSession($record['session']);
}
$lecture->setTime($record['time']);
$lecture->setSubject($record['subject']);
$student->setLecture($lecture);
$validationErrors = $this->validator->validate($student);
if (!count($validationErrors)) {
$this->em->persist($student);
$successful++;
}
if (($successful % $batchSize) == 0) {
$this->em->flush();
}
}
fclose($fp);
$csv->setImported(true);
$this->em->persist($csv);
$this->em->flush(); // Also persist objects that did not make up an entire batch
$results['successful'] = $successful;
$results['failed'] = $failed;
$results['exist'] = $exist;
return $results;
}