【问题标题】:Laravel 4, how to I create seed data to tables with relationships?Laravel 4,如何为具有关系的表创建种子数据?
【发布时间】:2013-06-27 17:46:43
【问题描述】:

我创建了一个包含两个表“goals”和“partgoals”的数据库。实际用途是制定储蓄目标(金钱)并在此过程中设定里程碑(部分目标)。我希望部分目标显然与特定目标相关联。关系已创建,但在尝试创建种子数据时遇到了麻烦。

我的目标是建立两个这样的目标表(GoalsTableSeeder.php):

<?php

class GoalsTableSeeder extends Seeder {

    public function run()
    {
        DB::table('goals')->delete();


        $goals = array(
            array(
                'max'      => 1850000,
                'avgsav' => 3500,
                'duedate'  => date('2015-03-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'max'      => 1100000,
                'avgsav' => 5000,
                'duedate'  => date('2013-11-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            )
        );

        DB::table('goals')->insert( $goals );
    }

}

我的 partgoals 表是这样的(PartgoalsTableSeeder.php):

<?php

class PartgoalsTableSeeder extends Seeder {

    public function run()
    {
        DB::table('partgoals')->delete();


        $partgoals = array(
            array(
                'id' => 1,
                'milestone'      => 100000,
                'duedate'  => date('2014-03-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'id' => 1,
                'milestone'      => 20000,
                'duedate'  => date('2013-06-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'id' => 2,
                'milestone'      => 400000,
                'duedate'  => date('2013-09-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'id' => 2,
                'milestone'      => 200000,
                'duedate'  => date('2014-10-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            )
        );

        DB::table('partgoals')->insert( $partgoals );
    }

}

“目标”的迁移表:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGoalsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('goals', function(Blueprint $table)
        {
            $table->increments('id');
            $table->integer('max');
            $table->float('avgsav');
            $table->date('duedate');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('goals');
    }

}

部分目标的迁移表:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePartgoalsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('partgoals', function(Blueprint $table)
        {
            $table->foreign('id')
                ->references('id')->on('goals')
                ->onDelete('cascade');
            $table->increments('id');
            $table->float('milestone');
            $table->date('duedate')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('partgoals');
    }

}

我做错了什么?我是 Laravel(和 Laravel 4)的新手。

【问题讨论】:

  • 您可能会从描述您遇到的麻烦中受益。是否有特定的错误消息/警告?是您的数据不存在/不符合预期吗?等
  • 抱歉,起初我似乎很清楚 =) 我在控制台中遇到了这个问题:[Exception] SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY' (SQL :插入partgoalsidmilestoneduedatecreated_atupdated_at)值(?,?,?,?,?),(?,?,?,?,? ), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)) 以及我要插入的数据。

标签: database foreign-keys laravel laravel-4 seeding


【解决方案1】:

我发现您的代码存在一些问题:

1) 创建外键的方式
在分配外键约束时,您应该将该列设为unsignedInteger
在下面的代码中,我将更正您将两列命名为“id”的错误

Schema::create('partgoals', function(Blueprint $table)
    {
        $table->increments('id');        
        $table->unsignedInteger('goal_id');
        $table->foreign('goal_id')
            ->references('id')->on('goals')
            ->onDelete('cascade');
        $table->float('milestone');
        $table->date('duedate')->nullable();
        $table->timestamps();
    });


2) 为数据库播种的方式
如果指定外键,则应在表播种器中创建条目时声明该值。
如果要指定 NULL 值,可以通过允许列接受这样的值来完成(默认情况下不接受)。在这种情况下,我们应该添加-&gt;nullable()-&gt;default(NULL)

Schema::create('partgoals', function(Blueprint $table)
    {
        $table->increments('id');        
        $table->unsignedInteger('goal_id')->nullable()->default(NULL);
        $table->foreign('goal_id')
            ->references('id')->on('goals')
            ->onDelete('cascade');
        $table->float('milestone');
        $table->date('duedate')->nullable();
        $table->timestamps();
    });

小错误
3)您在播种机中两次传递'id' =&gt; 1

【讨论】:

  • 这个文件在 Laravel 文件结构中的什么位置?
  • @AndrewKoper app/database/migrations
  • 你能举个例子说明“创建条目时声明值”是什么意思吗,我也在尝试为关系数据库做种
  • 只需使用'field' =&gt; 'value'。该部分的重点是:“如果它不可为空,则必须设置外键”
【解决方案2】:

在查询构建器中使用 increments 时,它会自动使您的主键自动递增且唯一。除非它是一对一的关系,否则您不能将外键也作为主键。但这只是糟糕的设计。您的架构应如下所示。

Schema::create('partgoals', function(Blueprint $table)
    {
        $table->increments('id');
        $table->foreign('goal_id')
            ->references('id')->on('goals')
            ->onDelete('cascade');
        $table->float('milestone');
        $table->date('duedate')->nullable();
        $table->timestamps();
    });

另外,在播种时,如果你在插入时使用insertGetId,它会返回你刚刚插入的记录的ID。这可以在另一个插入中使用,例如稍后插入另一个表。但是,这必须在同一个脚本中进行。您也许可以将其传回DatabaseSeeder,然后再传回另一个种子脚本,但我还没有尝试过。

【讨论】:

    【解决方案3】:

    我不熟悉 Laravel,或者您正在尝试做什么,但根据您在 cmets 中添加的错误,您的问题似乎是由于尝试使用相同的主键输入多条记录( 1) 进入您的partgoals 表。

    我不确定您是如何设置表的,但您似乎定义了一个带有唯一主键列 IDpartgoals 表,您还尝试将其用作引用goals 表的外键。在partgoals 表中创建另一个字段来保存您的外键可能值得。

    【讨论】:

      【解决方案4】:

      要播种有关系的表,需要在 ModelFactory.php 文件中定义模型工厂,然后创建播种器类来运行播种器。

      例如。模型工厂.php

      $factory->define(App\Category::class, function (Faker\Generator $faker) {
      
          $name = $faker->name;
      
          return [
              'name' => $name,
              'visible' => 1
          ];
      });
      
      $factory->define(App\Video::class, function (Faker\Generator $faker) {
      
          return [
              'title' => $faker->name,
              'description' => '',
              'status' => 1
          ];
      });
      

      那么seeder类可以如下

      <?php
      
      use Illuminate\Database\Seeder;
      
      class CategoriesTableSeeder extends Seeder
      {
          /**
           * Run the database seeds.
           *
           * @return void
           */
          public function run()
          {
              $categories = factory(App\Category::class, 20)->create()->each(function ($u) {
                      for ($i=0; $i<5; $i++)
                      {
                          $u->videos()->save(factory(App\Video::class)->make());
                      }
                  });
          }
      }
      

      您可以参考这篇文章,了解如何为关系为http://deepdivetuts.com/seeding-two-tables-using-laravel-5-3的两个表生成种子

      【讨论】:

        猜你喜欢
        • 2014-01-26
        • 2018-11-10
        • 1970-01-01
        • 2014-11-21
        • 2019-08-31
        • 1970-01-01
        • 2014-07-25
        • 2019-11-14
        • 2013-01-17
        相关资源
        最近更新 更多