介绍
伙计们,我对模型工厂和多个唯一列有疑问:
背景
我有一个名为Image的模型。此模型的语言支持存储在单独的模型ImageText中。ImageText具有image_id列,语言列和文本列。
ImageText在MySQL中有一个约束,即image_id和语言的组合必须唯一。
class CreateImageTextsTable extends Migration
{
public function up()
{
Schema::create('image_texts', function ($table) {
...
$table->unique(['image_id', 'language']);
...
});
}
...
Run Code Online (Sandbox Code Playgroud)
现在,我希望每个图像在完成播种后都具有多个ImageText模型。对于模型工厂和播种机,这很容易:
factory(App\Models\Image::class, 100)->create()->each(function ($image) {
$max = rand(0, 10);
for ($i = 0; $i < $max; $i++) {
$image->imageTexts()->save(factory(App\Models\ImageText::class)->create());
}
});
Run Code Online (Sandbox Code Playgroud)
问题
但是,当使用模型工厂和fakerr进行播种时,通常会看到以下消息:
[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '76-gn' for key 'image_texts_image_id_language_unique'
Run Code Online (Sandbox Code Playgroud)
这是因为在某个时候,在for循环内,伪造者将为图像随机两次使用相同的languageCode,从而打破了['image_id','language']的唯一约束。
您可以更新ImageTextFactory这样说:
$factory->define(App\Models\ImageText::class, …Run Code Online (Sandbox Code Playgroud) 我正在为内部 Laravel 应用程序开发一个包,但在运行包目录中存在的播种器时遇到问题。
在位于packages/vendor/packagename 的包的composer.json 文件中,我添加了以下内容:
"autoload": {
"psr-4": {
"Vendor\\PackageName\\": "src/",
"Vendor\\PackageName\\Database\\Factories\\": "database/factories/",
"Vendor\\PackageName\\Database\\Seeders\\": "database/seeders/"
}
},
Run Code Online (Sandbox Code Playgroud)
我有以下文件位于“packages/vendor/packagename/database/seeders/DepartmentSeeder.php”
<?php
namespace Vendor\PackageName\Database\Seeders;
use Illuminate\Database\Seeder;
use Vendor\PackageName\Models\Department;
class DepartmentSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Department::factory()->count(10)->create();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试运行以下命令:
$ php artisan db:seed --class="Vendor\\PackageName\\Database\\Seeders\\DepartmentSeeder"
Run Code Online (Sandbox Code Playgroud)
目标类 [Vendor\PackageName\Database\Seeders\DepartmentSeeder] 不存在。
如果我将播种机目录移至 src 目录并运行以下命令,它会起作用,但我宁愿将播种机保留在数据库目录中。
$ php artisan db:seed --class="Vendor\\PackageName\\seeders\\DepartmentSeeder"
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么找不到该课程吗?我所有的谷歌搜索结果都是紫色的,我什至去了第二页=/
就我的具体情况而言,composer dump-autoload并没有达到目的。我最终所做的就是跑步composer update vendor/packagename,无论问题是什么,它都得到了解决。
希望这对可能遇到类似问题的其他人有所帮助。
我正在阅读"Laravel 5 Essentials"中的教程.当我尝试使用命令播种数据库时
php artisan db:seed
我收到错误
[ReflectionException]
Class BreedsTableSeeder does not exist
Run Code Online (Sandbox Code Playgroud)
BreedsTableSeeder的代码定义如下:
<?
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class BreedsTableSeeder extends Seeder {
public function run()
{
DB:table('breeds')->insert([
['id' => 1, 'name' => "Domestic"],
['id' => 2, 'name' => "Persian"],
['id' => 3, 'name' => "Siamese"],
['id' => 4, 'name' => "Abyssinian"],
]);
}
}
Run Code Online (Sandbox Code Playgroud)
DatabaseSeeder定义如下:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function …Run Code Online (Sandbox Code Playgroud) 我有这个播种机功能。它获取所有插入的用户,然后为每个用户生成一个随机数(从 0 到 12)的个人资料图片。
public function run()
{
foreach (App\User::all() as $user) {
echo "Generating profile pic for $user->name ($user->id)... ";
$profile_pics = factory(App\Image::class, rand(0, 12))->create();
echo count($profile_pics) . " generated. ";
echo " Saving... ";
foreach ($profile_pics as $pp) {
$user->profile_pics()->save(App\Image::find($pp->id));
}
echo "Saved\n";
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,一些第一个随机用户的个人资料图片被正确插入。但失败后。
Generating profile pic for Amara Abbott I (1)... 5 generated. Saving... Saved
Generating profile pic for Major Crist (2)... 12 generated. Saving... Saved
Generating profile pic for Imelda Hettinger IV (3)... 3 …Run Code Online (Sandbox Code Playgroud) 所以我正在开发一个 Laravel 应用程序,并且我正在尝试优化我的种子,以便它们运行得更快。
http://bensmith.io/speeding-up-laravel-seeders
本指南帮助很大。据此,我应该通过大量插入来最大限度地减少 SQL 查询的数量,并将时间减少到原始播种时间的 10%,这真是太棒了。
所以现在我正在做类似的事情:
$comments = [];
for ($i = 0; $i < 50; $i++) {
$bar->advance();
$comments[] = factory(Comment::class)->make([
'created_at' => Carbon\Carbon::now(),
'updated_at' => Carbon\Carbon::now(),
'comment_type_id' => $comment_types->shuffle()->first()->id,
'user_id' => $users->shuffle()->first()->id,
'commentable_id' => $documents->shuffle()->first()->id,
])->toArray();
}
Comment::insert($comments);
Run Code Online (Sandbox Code Playgroud)
这就像一个魅力。它将查询缩减为单个查询。
但是我还有其他播种机来处理转储,它们更复杂:
$dump = file_get_contents(database_path('seeds/dumps/serverdump.txt'));
DB::table('server')->truncate();
DB::statement($dump);
$taxonomies = DB::table('server')->get();
foreach($taxonomies as $taxonomy){
$bar->advance();
$group = PatentClassGroup::create(['name' => $taxonomy->name]);
preg_match_all('/([a-zA-Z0-9]+)/', $taxonomy->classes, $classes);
foreach(array_pop($classes) as $key => $class){
$type = strlen($class) == 4 ? 'GROUP' : 'MAIN';
$inserted_taxonomies[] …Run Code Online (Sandbox Code Playgroud) 我在 Laravel 5.4 中播种,但它只播种一张桌子,其他桌子没有播种。播种机是使用以下命令创建的:
php artisan make:seeder seederName
Run Code Online (Sandbox Code Playgroud) 我已经播种了我的数据库php artisan db::seed.有没有办法回滚我播种到我的数据库中的内容.我似乎无法找到任何命令php artisan db::seed rollback
对于以下工厂定义,列order必须是顺序的.已经有一个id自动递增的列.第一行的order应该开始在1每个额外行的order应该是下一个号码(1,2,3等)
$factory->define(App\AliasCommand::class, function (Faker\Generator $faker) {
return [
'user_id' => App\User::inRandomOrder()->first()->id,
'command' => $faker->word,
'content' => $faker->sentence,
'order' => (App\AliasCommand::count()) ?
App\AliasCommand::orderBy('order', 'desc')->first()->order + 1 : 1
];
});
Run Code Online (Sandbox Code Playgroud)
它应该将order列设置为比前一行多1,但是,它会导致所有行都被分配1.
因此,类似于带有验证的唯一规则(请参阅:https : //github.com/felixkiss/uniquewith-validator),我想知道如何生成一个条目,其中一列与另一列是唯一的。我想按如下方式播种数据库。
例:
“步骤”表中有12个步骤。每个步骤应具有与每个步骤相关联的5个类别,这些类别存储在“ step_categories”表中。这些类别中的每一个都被分配一个唯一的订单号1到5,这对于每个“ step_id”都是唯一的。
请参见此图以获取数据库外观示例:https : //imgur.com/a/XYA5yyn
对于上述图像示例,我不得不手动在数据库中进行输入。我不想每次都必须手动生成它,例如说我犯了一个错误,而不必回滚迁移。
我正在使用工厂生成此数据。所以工厂名称是StepCategoriesFactory.php,显然我正在使用文件中的create()方法调用工厂DatabaseSeeder.php。
我考虑过要在for循环中执行此操作,然后我才意识到当我调用the 'step_id' => App\Model::all()->random()->id来获取新ID时,我无法确保我没有获取我刚刚为其生成5个条目的ID 。我真的是Laravel的新手,我不确定从哪里开始。没有关于SO的真实信息,伪造者可以在另一列中使用唯一性。我将如何处理?
注意:步骤ID并不总是将为1-12。步骤ID可能会有所不同,具体取决于步骤是否被删除并重新制作。因此,仅将分配step_id为等于1-12不会起作用。
更新:这是我刚刚编写的一些代码,我认为自己的方向正确。也许。我已经step_id按number字段抓取了,因为它始终是1-12,并且我已经从条目中抓取了IID。但是现在我被困在如何生成订单1-5而不重复自身的问题上。我还没有运行它,因为它不完整,我知道如果没有正确的订单号就会抛出错误。
更新2:我认为我在这里是对的。但是我收到一个未定义的变量错误。当我从匿名函数中放入第一行时,它会将每个条目的顺序重置为“ 1”。如何使$ autoIncrement变量可用于匿名函数?Seeder在两次更新之间保持不变。
错误图片:https : //imgur.com/a/ywkd0Lb终端中带有Die / Dump错误的第二张图片:https : //imgur.com/a/rOGRv32
在此处引用此文章:https : //laracasts.com/discuss/channels/laravel/model-factory-increment-value-faker?page=1
更新3:我忘记use ($autoIncrement)了匿名函数的代码行。下面的代码已更新,但是现在我收到另一个错误,指出订单列具有空值,无法插入。显然它应该是“ 1”。即使在我调用将$autoIncrement->next();其递增为“ 1”的my之后,它仍然会根据终端返回null。但是,当我对它进行一次死注时,$autoIncrement->current()它返回1.奇怪。
更新3错误:https : //imgur.com/a/STOmIjF
StepCategoriesFactory.php
use Faker\Generator as Faker;
$autoIncrement = autoIncrement();
$factory->define(App\StepCategory::class, function …Run Code Online (Sandbox Code Playgroud) 我收到错误“目标类 [Database\Seeders\UsersTableSeeder] 不存在”,我无法弄清楚原因。我已经尝试过针对类似问题发布的解决方案,但没有一个对我有用。
这是我的composer.json 自动加载/类映射设置
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeders",
"database/factories"
]
},
Run Code Online (Sandbox Code Playgroud)
UsersTableSeeder 类
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'fname' => 'Billy',
'lname'=> 'Bob',
'email' => 'billy@gmail.com',
'password' => Hash::make('12345678'),
]);
}
}
Run Code Online (Sandbox Code Playgroud)
数据库播种者类
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
* …Run Code Online (Sandbox Code Playgroud) laravel ×10
laravel-seeding ×10
php ×8
laravel-5.4 ×2
autoload ×1
factories ×1
faker ×1
laravel-5 ×1
mysql ×1
optimization ×1
package ×1
rollback ×1