Laravel 尝试为不需要的列设置种子
Laravel tries to seed column that is not asked for
我有一个奇怪的问题,在 Whosebug 上搜索和搜索了一个小时并没有让我更接近解决方案。发生的事情是,当我尝试播种 table(为了安全起见,我们称之为 my_table
)时,播种机似乎试图填充我从未要求播种的列。
所以,首先我 运行 php artisan migrate
使用以下迁移创建我的 table:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMyTableTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('my_table', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('user');
$table->tinyInteger('from_default')->nullable(false)->default(7);
$table->tinyInteger('to_default')->nullable(false)->default(20);
$table->timestamps();
$table->unique('user_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('my_table', function (Blueprint $table) {
$table->dropUnique(['user_id']);
$table->dropForeign(['user_id']);
});
}
}
这很好用,当我这样做时 DESCRIBE my_table
我得到以下信息:
Field Type Null Key Default Extra
-------------------------------------------------------------------------------
id int(10) unsigned NO PRI auto_increment
user_id int(10) unsigned NO UNI
from_default tinyint(4) NO 7
to_default tinyint(4) NO 20
created_at timestamp YES
updated_at timestamp YES
因此您可以看到 table 是使用我在迁移文件中想要的确切字段创建的。所以,现在我想使用以下种子为这个 table 播种:
<?php
use App\DomainLogic\Models\MyTable;
use App\DomainLogic\Models\User;
use Faker\Factory as FakerFactory;
use Illuminate\Database\Seeder;
class MyTableTableSeeder extends Seeder
{
/**
* @var array list of MyTable Users
*/
private $myTableUsers = [];
/**
* Run the database seeds.
*/
public function run()
{
$this->createMyTableUsers();
$myTableUsers = $this->getMyTableUsers();
foreach ($myTableUsers as $myTableUser) {
factory(MyTable::class)->create([
'user_id' => $myTableUser->getKey(),
'from_default' => 7,
'to_default' => 20,
]);
}
}
private function getMyTableUsers(): array
{
return $this->myTableUsers;
}
private function createMyTableUsers()
{
$faker = FakerFactory::create();
// My table
$this->myTableUsers[] = factory(User::class)->create([
'id' => 2,
'first_name' => 'Kalle',
'last_name' => 'Andersson',
'email' => 'kalle.andersson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
$this->myTableUsers[] = factory(User::class)->create([
'id' => 3,
'first_name' => 'Johan',
'last_name' => 'Petterson',
'email' => 'johan.petterson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
$this->myTableUsers[] = factory(User::class)->create([
'id' => 4,
'first_name' => 'Krister',
'last_name' => 'Johansson',
'email' => 'krister.johansson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
$this->myTableUsers[] = factory(User::class)->create([
'id' => 5,
'first_name' => 'Daniel',
'last_name' => 'Eriksson',
'email' => 'daniel.eriksson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
}
}
当 运行ning php artisan db:seed
我得到这个错误:
In Connection.php line 664:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'starts_day_default' in 'field list' (SQL: insert into `my_table` (`user_id`, `starts_day_default`, `ends_day_default`, `from_default`, `to_default`) values (2, 07, 20, 7, 20))
In PDOConnection.php line 82:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'starts_day_default' in 'field list'
In PDOConnection.php line 80:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'starts_day_default' in 'field list'
所以奇怪的是,据我所知,我从未尝试填充名为 starts_day_default
或 ends_day_default
的列。因为那些列不存在也不应该存在。实际情况是这些列已重命名为 starts_day_default -> from_default
和 ends _day_default -> to_default
。用户已正确创建,我可以在用户 table 中看到它们,所以这不是问题所在。这也是我的 MyTable 模型:
<?php
namespace App\DomainLogic\Models;
use DateTimeImmutable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class MyTable extends Model
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'my_table';
/**
* Creates personal trainer, if personal trainer with id exists.
*
* @param int $myTableId
*
* @return null|self
*/
public static function createFromId(int $myTableId): ?self
{
$myTable = self::select('my_table.*')
->join('user', 'user.id', '=', 'my_table.user_id')
->where('my_table.id', '=', $myTableId)
->whereNull('user.anonymized_at')
->get()
->first();
return $myTable;
}
/**
* Create personal trainer, if user_id exists.
*
* @param int $userId
*
* @return null|MyTable
*/
public static function createFromUserId(int $userId): ?self
{
return self::where('user_id', $userId)->get()->first();
}
/**
* Gets all personal trainers.
*
* @param bool $active
*
* @return Collection
*/
public static function getMyTables(bool $active = null): Collection
{
$query = self::select('my_table.*')
->join('user', 'user.id', '=', 'my_table.user_id')
->whereNull('user.anonymized_at');
if (isset($active)) {
$query->where('user.active', '=', $active);
}
$myTables = $query->get();
return $myTables;
}
/**
* Gets user.
*/
public function getUser(): User
{
$user = $this->belongsTo(User::class, 'user_id', 'id')->getResults();
return $user;
}
/**
* Check if personal trainers ids are valid.
*
* @param array $myTableIds
*
* @return bool
*/
public static function areMyTableIdsValid(array $myTableIds): bool
{
$dbMyTableIds = self::select('my_table.id')
->join('user', 'user.id', '=', 'my_table.user_id')
->whereIn('my_table.id', $myTableIds)
->whereNull('user.anonymized_at')
->get()
->pluck('id')
->toArray();
$dbMyTableIds = array_map('intval', $dbMyTableIds);
sort($myTableIds);
sort($dbMyTableIds);
$result = false;
if ($myTableIds === $dbMyTableIds) {
$result = true;
}
return $result;
}
}
我试过了
php artisan view:clear
php artisan cache:clear
php artisan debugbar:clear
composer dump-autoload
在 中建议,但这没有帮助。我已经删除了所有 tables 和 re运行 php artisan migrate
但这也没有帮助。
我以前从没见过这个,所以我的问题是,谁能看出我的问题是什么?
终于解决了,我错过了一个工厂文件 MyTableFactory
仍然包含错误的列。该文件非常隐蔽。
在我的例子中,文件在 database/factories 中。我建议遇到相同问题的任何人搜索名称中包含 Factory
的所有文件,然后搜索 Ctrl+F
在每个找到的文件中导致问题的列。
我有一个奇怪的问题,在 Whosebug 上搜索和搜索了一个小时并没有让我更接近解决方案。发生的事情是,当我尝试播种 table(为了安全起见,我们称之为 my_table
)时,播种机似乎试图填充我从未要求播种的列。
所以,首先我 运行 php artisan migrate
使用以下迁移创建我的 table:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMyTableTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('my_table', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('user');
$table->tinyInteger('from_default')->nullable(false)->default(7);
$table->tinyInteger('to_default')->nullable(false)->default(20);
$table->timestamps();
$table->unique('user_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('my_table', function (Blueprint $table) {
$table->dropUnique(['user_id']);
$table->dropForeign(['user_id']);
});
}
}
这很好用,当我这样做时 DESCRIBE my_table
我得到以下信息:
Field Type Null Key Default Extra
-------------------------------------------------------------------------------
id int(10) unsigned NO PRI auto_increment
user_id int(10) unsigned NO UNI
from_default tinyint(4) NO 7
to_default tinyint(4) NO 20
created_at timestamp YES
updated_at timestamp YES
因此您可以看到 table 是使用我在迁移文件中想要的确切字段创建的。所以,现在我想使用以下种子为这个 table 播种:
<?php
use App\DomainLogic\Models\MyTable;
use App\DomainLogic\Models\User;
use Faker\Factory as FakerFactory;
use Illuminate\Database\Seeder;
class MyTableTableSeeder extends Seeder
{
/**
* @var array list of MyTable Users
*/
private $myTableUsers = [];
/**
* Run the database seeds.
*/
public function run()
{
$this->createMyTableUsers();
$myTableUsers = $this->getMyTableUsers();
foreach ($myTableUsers as $myTableUser) {
factory(MyTable::class)->create([
'user_id' => $myTableUser->getKey(),
'from_default' => 7,
'to_default' => 20,
]);
}
}
private function getMyTableUsers(): array
{
return $this->myTableUsers;
}
private function createMyTableUsers()
{
$faker = FakerFactory::create();
// My table
$this->myTableUsers[] = factory(User::class)->create([
'id' => 2,
'first_name' => 'Kalle',
'last_name' => 'Andersson',
'email' => 'kalle.andersson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
$this->myTableUsers[] = factory(User::class)->create([
'id' => 3,
'first_name' => 'Johan',
'last_name' => 'Petterson',
'email' => 'johan.petterson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
$this->myTableUsers[] = factory(User::class)->create([
'id' => 4,
'first_name' => 'Krister',
'last_name' => 'Johansson',
'email' => 'krister.johansson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
$this->myTableUsers[] = factory(User::class)->create([
'id' => 5,
'first_name' => 'Daniel',
'last_name' => 'Eriksson',
'email' => 'daniel.eriksson@email.com',
'password' => bcrypt('password', ['rounds' => 4]),
'mobile_number' => $faker->e164PhoneNumber,
]);
}
}
当 运行ning php artisan db:seed
我得到这个错误:
In Connection.php line 664:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'starts_day_default' in 'field list' (SQL: insert into `my_table` (`user_id`, `starts_day_default`, `ends_day_default`, `from_default`, `to_default`) values (2, 07, 20, 7, 20))
In PDOConnection.php line 82:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'starts_day_default' in 'field list'
In PDOConnection.php line 80:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'starts_day_default' in 'field list'
所以奇怪的是,据我所知,我从未尝试填充名为 starts_day_default
或 ends_day_default
的列。因为那些列不存在也不应该存在。实际情况是这些列已重命名为 starts_day_default -> from_default
和 ends _day_default -> to_default
。用户已正确创建,我可以在用户 table 中看到它们,所以这不是问题所在。这也是我的 MyTable 模型:
<?php
namespace App\DomainLogic\Models;
use DateTimeImmutable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class MyTable extends Model
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'my_table';
/**
* Creates personal trainer, if personal trainer with id exists.
*
* @param int $myTableId
*
* @return null|self
*/
public static function createFromId(int $myTableId): ?self
{
$myTable = self::select('my_table.*')
->join('user', 'user.id', '=', 'my_table.user_id')
->where('my_table.id', '=', $myTableId)
->whereNull('user.anonymized_at')
->get()
->first();
return $myTable;
}
/**
* Create personal trainer, if user_id exists.
*
* @param int $userId
*
* @return null|MyTable
*/
public static function createFromUserId(int $userId): ?self
{
return self::where('user_id', $userId)->get()->first();
}
/**
* Gets all personal trainers.
*
* @param bool $active
*
* @return Collection
*/
public static function getMyTables(bool $active = null): Collection
{
$query = self::select('my_table.*')
->join('user', 'user.id', '=', 'my_table.user_id')
->whereNull('user.anonymized_at');
if (isset($active)) {
$query->where('user.active', '=', $active);
}
$myTables = $query->get();
return $myTables;
}
/**
* Gets user.
*/
public function getUser(): User
{
$user = $this->belongsTo(User::class, 'user_id', 'id')->getResults();
return $user;
}
/**
* Check if personal trainers ids are valid.
*
* @param array $myTableIds
*
* @return bool
*/
public static function areMyTableIdsValid(array $myTableIds): bool
{
$dbMyTableIds = self::select('my_table.id')
->join('user', 'user.id', '=', 'my_table.user_id')
->whereIn('my_table.id', $myTableIds)
->whereNull('user.anonymized_at')
->get()
->pluck('id')
->toArray();
$dbMyTableIds = array_map('intval', $dbMyTableIds);
sort($myTableIds);
sort($dbMyTableIds);
$result = false;
if ($myTableIds === $dbMyTableIds) {
$result = true;
}
return $result;
}
}
我试过了
php artisan view:clear
php artisan cache:clear
php artisan debugbar:clear
composer dump-autoload
在 php artisan migrate
但这也没有帮助。
我以前从没见过这个,所以我的问题是,谁能看出我的问题是什么?
终于解决了,我错过了一个工厂文件 MyTableFactory
仍然包含错误的列。该文件非常隐蔽。
在我的例子中,文件在 database/factories 中。我建议遇到相同问题的任何人搜索名称中包含 Factory
的所有文件,然后搜索 Ctrl+F
在每个找到的文件中导致问题的列。