【问题标题】:How to add a model with custom auto-increment primary key Laravel如何添加具有自定义自增主键 Laravel 的模型
【发布时间】:2018-07-30 13:35:58
【问题描述】:

我正在创建一个播种机,它将生产数据库中的数据(一部分)读取到我们的暂存环境中。

所以我得到了一个名为“类别”的模型,它的主键设置如下:

                                                             Table "public.categories"
     Column      |              Type              |                        Modifiers                        | 
-----------------+--------------------------------+---------------------------------------------------------+
 id              | integer                        | not null default nextval('categories_id_seq'::regclass) |

因为我从我的产品数据库中选择了几个类别,所以它的 id 不是连续的(它们看起来像这样:)

 id
-----
   3
   9
   7
   1
  11
  13
  15
  19
  21
  23
  25
  43
  45
  49
  51
  53
  55
  57
  61

现在我还有一个自定义播种器文件,我想在其中创建虚假类别。自然,我必须确保创建的类别的 ID 大于具有最高 ID 的类别。我是这样做的:

$factory->define(App\Category::class, function (Faker\Generator $faker) {
    // to avoid duplicating ids
    $lastCategory = Category::select('id')->orderBy('id','desc')->first();

    $category = new Category();
    $category->id  = $lastCategory->id+1;
    $category->ref = str_random(20);
    $category->image = $faker->imageUrl(300, 300);
    $category->priority = rand(0, 100);
    $category->save();

但我不断收到此错误:

[Illuminate\Database\QueryException] SQLSTATE[23505]:唯一 违规:7 错误:重复键值违反唯一约束 “categories_pkey”详细信息:密钥 (id)=(13) 已存在。 (SQL: 插入“类别”(“ref_translation”,“ref”,“parent_id”, “top_parent_id”、“图像”、“优先级”、“updated_at”、“created_at”) 值(translatable.category.ref.HDHCDuNPC4vZoHBB,三明治,124, 124,https://cdn.filepicker.io/api/file/TqB5OvCdSxGDFecrSyrU,0, 2018-02-20 08:38:20,2018-02-20 08:38:20)返回“id”)

[Doctrine\DBAL\Driver\PDOException] SQLSTATE[23505]:唯一 违规:7 错误:重复键值违反唯一约束 "categories_pkey" DETAIL: Key (id)=(13) 已经存在。

虽然与原始的 postgresql 语句相同,但效果很好:

insert into categories (id, ref_translation,ref,image,priority) values (200, 'translatable.category.ref.ZAxcHj4hOziemQyz', 'LP2a1bY81IGSza0eHVSqdfsdfdsffds', 'image_name', 1);
INSERT 0 1

如何通过 Laravel 的 Eloquent ORM 实现这一点?

更新

作为参考,这是我的类生成器的样子:

$factory->define(App\Category::class, function (Faker\Generator $faker) {
    $category = App\Category::create([
        'ref'      => str_random(20),
        'image'    => $faker->imageUrl(300, 300),
        'priority' => rand(0, 100),
    ]);
    $top_parent_id = $category->id;

    return [
        'ref'           => str_random(21),
        'parent_id'     => $top_parent_id,
        'top_parent_id' => $top_parent_id,
        'image'         => $faker->imageUrl(300, 300),
        'priority'      => rand(0, 100),
    ];
});

【问题讨论】:

  • 你尝试更新 Laravel 了吗?

标签: php laravel postgresql orm eloquent


【解决方案1】:

这让它工作了

$lastCategory = \App\Category::orderBy('id','desc')->first();
\DB::statement('alter sequence categories_id_seq restart with '.(intval($lastCategory->id)+1)); 

参考文献

【讨论】:

  • 嗯,这不是一件可怕的事,要投反对票,以后会在路上咬你
  • 怎么回事?我希望你得到的不仅仅是:因为我说过.. 请记住,这是开发环境,所有种子数据都是假的,随后输入的数据也是如此
  • 基本上 $lastCategory = \App\Category::orderBy('id', 'desc')->first();然后 $newFreakCategory = $lastCategory->replicate();
  • 你测试过吗?
  • 这并没有告诉我有关表的 id_sequence 的任何信息
【解决方案2】:

由于某种原因,它似乎正在插入一条 id = 13 的新记录

// this is another way, however you need a PDO object for it
$lastId = DB::getPdo()->lastInsertId();

尝试删除:

// ->id because the $lastCategory contains the last integer
$category->id  = ((int)$lastCategory +1);

【讨论】:

    【解决方案3】:

    在定义列本身时,在 Model 中使用 Laravel 的 increments() 方法。 检查doc here。这将负责增加新插入的 ID。

    这种方法也有 int、bigint 和 tinyint 的变体。

    【讨论】:

    • 那行不通..仅仅为了让播种机开心而修改生产数据库的结构没有任何意义..播种机必须在不改变现有数据库模式的情况下工作
    猜你喜欢
    • 2019-05-11
    • 2020-02-10
    • 2016-09-11
    • 2018-10-17
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 2018-05-31
    • 2018-06-05
    相关资源
    最近更新 更多