防止播种唯一的密钥违规

时间:2015-08-12 16:55:14

标签: php database laravel seeding faker

我的数据库中有两列唯一约束。

$table->unique(array("table_a_id", "table_b_id"));

现在我在播种器类中使用Faker来填充此数据透视表:

$tableAIds = TableA::all()->lists("id")->toArray();
$tableBIds = TableB::all()->lists("id")->toArray();

foreach(range(1, 20) as $index) {
    $tableAId = $faker->randomElement($tableAIds);
    $tableBId = $faker->randomElement($tableBIds);

    DB::table("table_a_table_b_pivot")->insert([
        "table_a_id" => $tableAId,
        "table_b_id" => $tableBId
    ]);
}

然而,这会导致重复,并且由于SQL错误而导致播种失败。

如何确保我不尝试插入重复项?

3 个答案:

答案 0 :(得分:0)

您可以使用:

$tableAIds = TableA::all()->lists("id")->toArray();
$tableBIds = TableB::all()->lists("id")->toArray();
foreach (range(1, 20) as $index) {
    repeat:
    $tableAId = $faker->randomElement($tableAIds);
    $tableBId = $faker->randomElement($tableBIds);
    try {
        DB::table("table_a_table_b_pivot")->insert([
            "table_a_id" => $tableAId,
            "table_b_id" => $tableBId,
        ]);
   } catch (\Illuminate\Database\QueryException $e) {
            //look for integrity violation exception (23000)
            if($e->errorInfo[0]==23000)
              goto repeat;
   }
}

Ps:如果从开始的TableA和TableB数据不一致(这意味着不可能从这些数据形成20个唯一的夫妇),这可能不起作用。

答案 1 :(得分:0)

$unique = $faker->unique()->regexify('[0-4][0-9][0-4][0-9]');

上面的代码将产生一个由0到49之间的两个数字组成的字符串,它们永远不会重复。现在,您可以分成两个并安全地为数据库设定种子。

$firstId = ltrim(substr($unique, 0, 2), '0') + 1;
$secondId = ltrim(substr($unique, 2, 2), '0') + 1;

字符串中的两个数字可以相同,但字符串始终是唯一的。不要忘记为每个部分添加一个,因为我们不想(并且我们不能)用零种子数据库。

答案 2 :(得分:-1)

使用集合的2015-07-25 14:54:50.786774,1,0,439.85,,,,0,0,方法

,而不是使用faker
random

根据您的需要进行调整。

例如,这可能是您真正想要的:

$tableAIds = TableA::all()->lists('id')->random(20);
$tableBIds = TableB::all()->lists('id')->random(20);

foreach(range(0, 19) as $index) {
    DB::table("table_a_table_b_pivot")->insert([
        "table_a_id" => $tableAIds[$index],
        "table_b_id" => $tableBIds[$index],
    ]);
}

无论是什么,自己玩吧。这里不需要骗子。