Database Seeder和Laravel

时间:2019-12-11 11:56:08

标签: laravel faker

我有3个表,架构如下。 员工

EmployeeDB.php

$factory->define(Employee::class, function (Faker $faker) {
    return [
        'emp_id' => $faker->randomDigit,
        'name' => $faker->name,
        'dept_id' => $faker->numberBetween($min = 1, $max = 15),
        'salary_id' => $faker->randomDigit(),
        'gender' => $faker->randomElement(['M', 'F', 'T']),
       /*if I remove these next 2 statements, I receive an error for 
       SQLSTATE[42S22]: Column not found: 1054 Unknown column 
       'employee_id' in 'field list' (SQL: insert into `employees` (`emp_id`, `name`, `dept_id`, `salary_id`, `gender`, `date_of_joining`,
        `date_of_birth`, `employee_id`, `updated_at`, `created_at`) values (2, Jamaal Beer, 3, 9, T, 2018-05-05 18:59:40, 2005-07-05 13:17:23, ?, 
        2019-12-11 11:15:42, 2019-12-11 11:15:42))
       */ 
       'employee_id' => $faker->randomDigit,
       //Same for this one as well
        'department_id' => $faker->randomDigit,
        'date_of_joining' => $faker->dateTimeBetween($startDate = '-5 years', $endDate = 'now', $timezone = null),
        'date_of_birth' => $faker->dateTimeBetween($startDate = '-20 years', $endDate = 'now', $timezone = null),

员工迁移表:

Schema::create('employees', function (Blueprint $table) {
        $table->bigIncrements('emp_id');
        $table->integer('dept_id')->unsigned();
        $table->foreign('dept_id')->references('id')->on('departments');
        $table->integer('salary_id')->unsigned();
        $table->foreign('salary_id')->references('id')->on('salaries');
        $table->string('name');
        $table->string('gender');
        $table->timestamp('date_of_joining');
        $table->dateTime('date_of_birth');
        /*SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'employee_id' cannot be null 
        (SQL: insert into `employees` (`emp_id`, `name`, `dept_id`, `salary_id`, `gender`, `employee_id`, `department_id`, 
        `date_of_joining`, `date_of_birth`, `updated_at`, `created_at`) 
        values (6, Martina Wuckert, 7, 3, F, ?, 3, 2018-09-14 05:59:15, 20
        */
        $table->string('employee_id')->nullable();
        $table->string('department_id')->nullable();
        $table->timestamps();
        //added to prevent errors

部门 DepartmentsDB.php

factory->define(Department::class, function (Faker $faker) {
return [
    //Yes, this is a hack. Use Multidimensional Arrays the next time.
    'id' => $faker->numberBetween($min = 1, $max = 15),
    'dept_name' => $faker->randomElement(['Production', 'Purchase & Quality', 'Operations', 'Sales', 'Customer Serice', 'Business Development', 'Maketing', 'Tech Support', 'Finance', 'Human Resources', 'Research & Development', 'IT', 'Legal']),
];

部门迁移

Schema::create('departments', function (Blueprint $table) {
        $table->increments('id');
        $table->string('dept_name');
        $table->timestamps();
    });

工资

SalaryDb.php

$factory->define(Salary::class, function (Faker $faker) {
    return [
        'id' => $faker->randomDigit(),
        'monthlySalary' => $faker->randomNumber($nbDigits = 3),
        //Yes this is a hack. Use MultiDimensional Arrays the next time.
    ];
});

薪酬迁移

$factory->define(Salary::class, function (Faker $faker) {
    return [
        'id' => $faker->randomDigit(),
        'monthlySalary' => $faker->randomNumber($nbDigits = 3),
        //Yes this is a hack. Use MultiDimensional Arrays the next time.
    ];
});

应用程序\部门 班级部门扩展模型

{  
    //
    public function employee()
    {
        return $this->hasMany(Employee::class);
    }
    public function salary()
    {
        return $this->hasMany(Salary::class);
    }
}

App \ Employee

class Employee extends Model
    {  //belongsto  block
        public function department()
        {
            return $this->hasOne(Department::class);
        }
        public function Salary()
        {
            return $this->hasOne(Salary::class);
        }
    }

App \ Salary

    class Salary extends Model
{
    //
    public function employee()
    {
        return $this->belongsTo(Employee::class);
    }
}

DatabaseSeeder.php

 factory(App\Employee::class, 25)->create()->each(function ($employee) {
        $department = factory(App\Department::class)->make();
        $employee->department()->save($department);
        $salary = factory(App\Salary::class)->make();
        $employee->salary()->save($salary);
    });

当我运行以下命令时,这是我得到的错误     php artisan db:seed

Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`volga_2`.`employees`, CONSTRAINT `employees_dept_id_foreign` FOREIGN KEY (`dept_id`) REFERENCES `departments` (`id`))")

我想做的是:为每份员工记录分配一个部门和一个薪水。

这将在以后提供:部门不能在其自己的表中重复。就是创建具有名称的部门ID后,将无法再次创建它。

我知道我做错了,否则不会出现错误。当我为部门和薪水运行dbSeeder时,它工作正常。但是,只要有重复的部门条目,就会引发错误。但是存储在数据库中的数据很好。

我想要一个解决方案或一些建议,因为我仍在学习Laravel。

谢谢!

编辑 当我执行     php artisan migration

迁移顺序

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.44 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (1.18 seconds)
Migrating: 2019_12_09_105432_create_departments_table
Migrated:  2019_12_09_105432_create_departments_table (0.29 seconds)
Migrating: 2019_12_09_105743_create_salaries_table
Migrated:  2019_12_09_105743_create_salaries_table (0.21 seconds)
Migrating: 2019_12_10_104739_create_employees_table
Migrated:  2019_12_10_104739_create_employees_table (2.04 seconds)

3 个答案:

答案 0 :(得分:2)

只需更改迁移顺序。我猜您正在尝试在创建表之前建立关系。进行父表的第一次迁移

答案 1 :(得分:0)

Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`volga_2`.`employees`, CONSTRAINT `employees_dept_id_foreign` FOREIGN KEY (`dept_id`) REFERENCES `departments` (`id`))")

此错误表明由于某种原因它无法与部门表生成关系。在编写时,您尝试在生成其他2个表之前生成Employee,通过更改迁移名称可以对迁移进行重新排序。这意味着您可以通过更改迁移名称中的时间来更改运行迁移的顺序,以便按照以下顺序进行迁移:

1)部门迁移

2)SalariesMigration

3)员工迁移

答案 2 :(得分:0)

谢谢大家提供的解决方案和想法,以帮助我解决此问题。但是在修改之后,我制定了一个很好的解决方案。 我将只发布所做的更改,以使跟踪变得更容易,这可能会对其他人有所帮助。

在这里。

EmployeeDB.php

$factory->define(Employee::class, function (Faker $faker) {
    return [
        'emp_id' => $faker->unique()->randomNumber($nbDigits = 3, $strict = true),
        'name' => $faker->name,
        //dept_id and salary_id pulls the data from their respective tables and then //randomly assigns an id from the id column
        'dept_id' => App\Department::all()->random()->id,
        'salary_id' => App\Salary::all()->random()->id,
        'gender' => $faker->randomElement(['M', 'F', 'T']),
        'date_of_joining' => $faker->dateTimeBetween($startDate = '-5 years', $endDate = 'now', $timezone = null),
        'date_of_birth' => $faker->dateTimeBetween($startDate = '-20 years', $endDate = 'now', $timezone = null),

    ];
});

EmployeeMigration

public function up()
    {
        Schema::create('employees', function (Blueprint $table) {
            $table->unsignedInteger('emp_id', true);
            $table->unsignedInteger('dept_id');
            $table->foreign('dept_id')->references('id')->on('departments');
            $table->unsignedInteger('salary_id');
            $table->foreign('salary_id')->references('id')->on('salaries');
            $table->string('name');
            $table->string('gender');
            $table->timestamp('date_of_joining');
            $table->dateTime('date_of_birth');
            $table->timestamps();
            //added to prevent errors
        });

部门数据库

$factory->define(Department::class, function (Faker $faker) {
    return [
        //Yes, this is a hack. Use Multidimensional Arrays the next time.
        'id' => $faker->unique()->numberBetween(1, 12),
        'dept_name' => $faker->randomElement(['Production', 'Purchase & Quality', 'Operations', 'Sales', 'Customer Serice', 'Business Development', 'Maketing', 'Tech Support', 'Finance', 'Human Resources', 'Research & Development', 'IT', 'Legal']),
    ];
});

部门迁移

 protected $dept_id = 'id';
public function up()
    {

        Schema::create('departments', function (Blueprint $table) {
            $table->unsignedInteger('id', true);
            $table->string('dept_name');
            $table->timestamps();
        });
    }

SalaryDB

$factory->define(Salary::class, function (Faker $faker) {
        return [
            'id' => $faker->unique()->randomNumber($nbDigits = 5, $strict = true),
            'monthlySalary' => $faker->randomNumber($nbDigits = 3),
            //Yes this is a hack. Use MultiDimensional Arrays the next time.
        ];
    });

工资迁移

public function up()
    {
        Schema::create('salaries', function (Blueprint $table) {
            $table->unsignedInteger('id', true);
            $table->string('monthlySalary');
            $table->timestamps();
        });
    }

DatabaseSeeder.php

 public function run()
    {
        $this->call([UsersTableSeeder::class]);//this is not important
        factory('App\Department', 12)->create();
        factory('App\Salary', 50)->create();
        factory('App\Employee', 55)->create();
    }
}

发生的事情是,我首先为Departments表添加了部门ID和它们各自的名称。然后,我在工资表中播种了工资表,其中仅包含工资编号和工资金额。 然后,员工播种机开始运行,它通过外键关系引用了部门和薪水表,并将这些表中的ID列中的数据插入到我的员工表中的dept_id和salary_id列中。

另一个重要方面是,设置主键是使用

protected $id = 'Primary Key Table name'

请参见上面的DepartmentMigration代码块。这需要在up()函数范围之外定义,并且必须在需要定义主键的任何地方都存在。

我已经完成了3个多小时,分别完成了每个DB Seeder的工作,因此我很高兴这项工作。可能会有更好,更优雅的解决方案,但明天我会继续讨论。 :)

感谢您阅读,希望对您有所帮助。 我将尽我所能回答有关此问题。 :)