按照标题,我在每行中都有一个包含所有数据(父/子)的excel文件。 Laravel Excel网站显示了如何导入,假设每行只有一个模型-但是如何导入子数据? https://laravel-excel.maatwebsite.nl/3.1/imports/
例如“伪”模式:
Vector
例如,文件:students.xlsx
Schema::create('students', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('student_code',16);
$table->string('student_name',64);
$table->string('student_surname',64);
});
Schema::create('student_courses', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->integer('student_id')->unsigned()->index();
$table->string('course', 32);
$table->date('start_date');
$table->date('end_date');
$table->timestamps();
});
Schema::create('student_contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->integer('student_id')->unsigned()->index();
$table->string('contact_name', 32);
$table->string('contact_number', 32);
$table->timestamps();
});
假设我的导入代码:
Student Code | Student Name | Student Surname | Course | Course Start Date | Course End Date | Contact Person | Contact Numbers
ABC1 | Arnold | Clarp | C++ | 2019-01-01 | 2019-12-01 | Boogle | 555-111-222
DEF2 | Delta | Flork | English | 2019-01-02 | 2019-12-02 | Google | 555-111-333
GHI3 | Goblin | Clark | Science | 2019-01-03 | 2019-12-03 | Foogle | 555-111-444
我实际上将在哪里插入“子”课程/联系方式数据的导入? 我猜想不是“返回新学生”,而是要先将其分配给变量,然后再将其导入?这是正确的方法吗? 例如:
class StudentsImport implements ToModel, WithStartRow
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
return new Student([
'student_code' => $row[1],
'student_name' => $row[2],
'student_surname' => $row[3],
]);
}
/**
* @return int
*/
public function startRow(): int
{
return 2;
}
}
//按实际情况显示的代码,不再是'pseudo':
public function model(array $row)
{
$student = new Student([
'student_code'=> $row[1],
'student_name'=> $row[2],
'student_surname'=> $row[3],
])
$student->courses()->create([
'course'=>$row[4],
'start_date'=>$row[5],
'end_date'=>$row[6]
]);
$student->contacts()->create([
'contact_name'=>$row[7],
'contact_number'=>$row[8]
]);
return $student;
}
错误(错误未通过父ID传递)
SQLSTATE [23000]:违反完整性约束:1048列'student_id'不能为空(SQL:插入 $student = new Student([
'bursary_provider_id' => 1,
'bursary_provider_reference' => 'xxx',
'student_name' => $row[1],
'student_initials' => $row[3],
'student_surname' => $row[2],
'passport_number' => $row[7],
'passport_expiration' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[9]),
'country_id' => 7,
'id_number' => $row[6],
'status' => $status,
'notes' => $row[5]
]);
if (isset($row[10])) {
$student->visas()->create([
'country_id' => 201,
'visa_reference_number' => $row[10],
'visa_expiration_date' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[11])
]);
(student_visas
,country_id
,visa_reference_number
,{ {1}},visa_expiration_date
,student_id
)值(201,ABCHFV4,2019-12-31 00:00:00,,2019-01-11 08:03:06,2019-01- 11 08:03:06))
答案 0 :(得分:0)
答案(不要问我为什么,因为在这个阶段文档太少了)就是使用集合。
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
,而不是ToModel:
public function collection(Collection $rows)
,它不会“返回”任何东西。除了这些更改之外,在OP中使用完全相同的代码可以按预期工作。
答案 1 :(得分:0)
您收到此错误,因为该学生尚未写入数据库,因此没有为新的学生实例分配ID。如果使用集合,则数据将立即写入数据库。在模型功能中,您可以使用
$student=Student::Create(['bursary_provider_id' => 1,
'bursary_provider_reference' => 'xxx',
'student_name' => $row[1],
'student_initials' => $row[3],
'student_surname' => $row[2],
'passport_number' => $row[7],
'passport_expiration' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[9]),
'country_id' => 7,
'id_number' => $row[6],
'status' => $status,
'notes' => $row[5]]);
这会将学生写入数据库并生成必要的ID。我不确定这如何影响性能。