I am having the following db tables
// Table 1: Foos
id, foo_name, foo_type, created_at, updated_at
// Table 2: Bars
id, bar_name, bar_type, parent_id, foo_id [ForeignKey], created_at, updated_at
// Table 3: Quxes
id, qux_name, bar_id [ForeignKey], created_at, updated_at
And I am having the following seeders setup
class FooSeeder extends Seeder
{
public function run()
{
\App\Models\Qux::truncate();
\App\Models\Bar::truncate();
\App\Models\Foo::truncate();
\App\Models\Foo::create([
'foo_name' => 'Foo',
'foo_type' => 'Foo type',
]);
}
}
class BarSeeder extends Seeder
{
public function run()
{
\App\Models\Qux::truncate();
\App\Models\Bar::truncate();
\App\Models\Bar::create([
'bar_name' => 'Bar',
'bar_type' => 'Bar type',
'foo_id' => 1,
'parent_id' => 1,
]);
\App\Models\Bar::create([
'bar_name' => 'Bar Bar',
'bar_type' => 'Bar Bar type',
'foo_id' => 1,
'parent_id' => 0,
]);
}
}
class QuxSeeder extends Seeder
{
public function run()
{
\App\Models\Qux::truncate();
\App\Models\Bar::truncate();
\App\Models\Qux::create([
'qux_name' => 'Qux',
'bar_id' => 1,
]);
\App\Models\Qux::create([
'qux_name' => 'Qux Qux',
'bar_id' => 1,
]);
}
}
When I try to run php artisan db:seed I get the following error
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (`mylaravelschema`.`quxes`, CONSTRAINT `qux_bar_id_foreign` FOREIGN KEY (`bar_id`) REFERENCES `mylaravelschema`.`bars` (`id`)) (SQL: truncate table `bars`)
I have been trying to play with the order of truncating the tables on these three seeders and still haven't manage to sort this, any help appreciated.
use it like this
class FooSeeder extends Seeder
{
public function run()
{
\App\Models\Foo::truncate();
\App\Models\Bar::truncate();
\App\Models\Qux::truncate();
\App\Models\Foo::create([
'foo_name' => 'Foo',
'foo_type' => 'Foo type',
]);
}
}
class BarSeeder extends Seeder
{
public function run()
{
\App\Models\Bar::create([
'bar_name' => 'Bar',
'bar_type' => 'Bar type',
'foo_id' => 1,
'parent_id' => 1,
]);
\App\Models\Bar::create([
'bar_name' => 'Bar Bar',
'bar_type' => 'Bar Bar type',
'foo_id' => 1,
'parent_id' => 0,
]);
}
}
class QuxSeeder extends Seeder
{
public function run()
{
\App\Models\Qux::create([
'qux_name' => 'Qux',
'bar_id' => 1,
]);
\App\Models\Qux::create([
'qux_name' => 'Qux Qux',
'bar_id' => 1,
]);
}
}
please use this hierarchy level because you've the foreign keys and when you're going to truncate it cannot find the reference one
Hope it helps
Related
I have an error on Laravel 9 when run seeder, its say Array to string conversion
I have a same seeder type json before this DataMaster table, and its working. But when i run DataMasterSeeder, its not working
My seeder:
<?php
namespace Database\Seeders;
use App\Models\DataMaster;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DataMasterSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
//SDU
DataMaster::create(['formId' => 1, 'userId' => 1, 'kecamatanId' => 1, 'desaId' => null, 'fieldDatas' => [['id' => '1', 'name' => 'jumlah', 'title' => 'Jumlah', 'value' => '4605']], 'level' => 'kecamatan']);
}
}
And my DataMaster migration:
public function up()
{
Schema::create('data_masters', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('formId');
$table->unsignedBigInteger('userId');
$table->unsignedBigInteger('kecamatanId')->nullable();
$table->unsignedBigInteger('desaId')->nullable();
$table->json('fieldDatas');
$table->enum('level', ['kecamatan', 'desa']);
$table->timestamps();
$table->foreign("formId")->references("id")->on("forms")->onDelete('cascade');
$table->foreign("userId")->references("id")->on("users")->onDelete('cascade');
$table->foreign("kecamatanId")->references("id")->on("kecamatans")->onDelete('cascade');
$table->foreign("desaId")->references("id")->on("desas")->onDelete('cascade');
});
}
I have another seeder like fieldDatas json field in this DataMaster seeder, and i run it successfully before run DataMaster seeder.
you should encode the field fieldDatas before inserting
DataMaster::create([
'formId' => 1,
'userId' => 1,
'kecamatanId' => 1,
'desaId' => null,
// here...
'fieldDatas' => json_encode([['id' => '1', 'name' => 'jumlah', 'title' => 'Jumlah', 'value' => '4605']]),
'level' => 'kecamatan',
]);
I'm seeding the test database with fake users, posts and categories but for some reason when I seed the database with more than 15 records Laravel throws this error:
Illuminate\Database\QueryException
SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: categories.name (SQL: insert into "categories" ("name", "slug", "updated_at", "created_at") values (id, quibusdam-nihil-dignissimos-vitae-sint-minus-est-nostrum, 2021-06-22 17:52:02, 2021-06-22 17:52:02))
If I seed 15 or less records at once works fine.
This is the database seeder:
User::truncate();
Post::truncate();
Category::truncate();
Post::factory(15)->create();
The Post factory:
public function definition()
{
return [
'user_id' => User::factory(),
'category_id' => Category::factory(),
'title' => $this->faker->sentence,
'slug' => $this->faker->slug,
'excerpt' => $this->faker->sentence,
'body' => $this->faker->paragraph
];
}
And the category factory:
public function definition()
{
return [
'name' => $this->faker->word,
'slug' => $this->faker->slug
];
}
I'm using Laravel 8 and the database is sqlite.
I am trying to create a seeder that fills a databases with "Assignments" that are linked with a "Course" database with foreign key constraint.
Since i am pretty new to PHP and Laravel 6 in general i don't really know where to start.
I allready have a seeder that fills my "Course" database, which like this:
class CoursesTableSeed extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('courses')->insert([[
'name' => 'Opleidings- en beroepsoriëntatie',
'ecs' => '2.5'
],[
'name' => 'Computer science basics',
'ecs' => '7.5'
],[
'name' => 'Programming basics',
'ecs' => '5'
],[
'name'=>'Professional skills 1',
'ecs'=>'2.5',
],[
'name'=>'HZ Personality',
'ecs'=>'2.5',
],[
'name'=>'Object-oriented programming',
'ecs'=>'10',
],[
'name'=>'Professional skills 2',
'ecs'=>'2.5',
],[
'name'=>'Professionele werkplek',
'ecs'=>'2.5',
],[
'name'=>'Framework development 1',
'ecs'=>'5',
],[
'name'=>'Framework project 1',
'ecs'=>'5',
],[
'name'=>'Professional skills 3',
'ecs'=>'2.5',
],[
'name'=>'IT Personality 1',
'ecs'=>'2.5',
],[
'name'=>'Framework development 2',
'ecs'=>'5',
],[
'name'=>'Framework project 2',
'ecs'=>'5',
]
]);
}
}
Now i want to do the same thing with my assignment database but i cant figure out how since i also want to have the "Assignments" linked with theyr respective "Course" so when i delete a course it also deletes it associated assignments. If this question comes over a little vague, sorry for that. I am pretty new to PHP laravel and programming in general.
Also, this is my migration for the assignments:
class CreateAssignmentsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('assignments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('course_id');
$table->text('name');
$table->decimal('weight',3,1)->nullable();
$table->decimal('grade', 3, 1)->nullable();
$table->timestamps();
$table->foreign('course_id')
->references('id')
->on('courses')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('assignments');
}
}
Welcome to Stackoverflow!
You can seed your assignments in different ways. For example: update existing seeder, or create another seeder.
Here code for another seeder (you must have Course and Assignment models):
<?php
use App\Assignment;
use App\Course;
use Illuminate\Database\Seeder;
class AssignmentsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$data = [
[
'name' => 'Opleidings- en beroepsoriëntatie',
'assignments' => [
[
'name' => 'Assignment 1',
'weight' => 1.5,
'grade' => 1.1,
],
[
'name' => 'Assignment 2',
'weight' => 2.0,
'grade' => 1.2,
],
]
],
[
'name' => 'Computer science basics',
'assignments' => [
[
'name' => 'Assignment 3',
'weight' => 1.5,
'grade' => 1.0,
],
[
'name' => 'Assignment 4',
'weight' => 1.5,
'grade' => 1.0,
],
[
'name' => 'Assignment 5',
'weight' => 1.5,
'grade' => 1.0,
],
]
],
];
// Loops through courses
foreach ($data as $key => $value) {
$course = Course::where('name', $value['name'])->first();
if ($course instanceof Course) {
if (isset($value['assignments']) && is_array($value['assignments'])) {
// Loops through assignments
foreach ($value['assignments'] as $assignment) {
$assignment['course_id'] = $course->id;
Assignment::firstOrCreate($assignment);
}
}
}
}
}
}
Put this code to database/seeds/AssignmentsTableSeeder.php file and after that call this console commands:
composer dump-autoload
php artisan db:seed --class=AssignmentsTableSeeder
After that you will get the following result
There is 2 tables many-to-manty and another Intermediary able
$this->createTable('tweet',[
'id' => Schema::TYPE_PK,
'text' => Schema::TYPE_STRING.' NOT NULL',
'date_written' => Schema::TYPE_STRING.' NOT NULL',
'date_imported' => Schema::TYPE_STRING.' NOT NULL',
],"ENGINE=InnoDB DEFAULT CHARSET=utf8");
$this->createTable('hashtag',[
'text' => $this->string(),
'PRIMARY KEY(text)'
],"ENGINE=InnoDB DEFAULT CHARSET=utf8");
$this->createTable('tweet_hashtag', [
'tweet_id' => $this->integer(),
'hashtag_text' => $this->string(),
'PRIMARY KEY(tweet_id, hashtag_text)'
],"ENGINE=InnoDB DEFAULT CHARSET=utf8");
$this->createIndex('idx-tweet_hashtag-tweet_id', 'tweet_hashtag', 'tweet_id');
$this->createIndex('idx-tweet_hashtag-hashtag_text', 'tweet_hashtag', 'hashtag_text');
$this->addForeignKey('fk-tweet_hashtag-tweet_id', 'tweet_hashtag', 'tweet_id', 'tweet', 'id', 'CASCADE');
$this->addForeignKey('fk-tweet_hashtag-hashtag_text', 'tweet_hashtag', 'hashtag_text', 'hashtag', 'text', 'CASCADE');
Table Tweet
public function getTweetHashtags()
{
return $this->hasMany(TweetHashtag::className(), ['tweet_id' => 'id']);
}
public function getHashtagTexts()
{
return $this->hasMany(Hashtag::className(), ['text' => 'hashtag_text'])->viaTable('tweet_hashtag', ['tweet_id' => 'id']);
}
Table tweet_hashtag
public function getHashtagText()
{
return $this->hasOne(Hashtag::className(), ['text' => 'hashtag_text']);
}
public function getTweet()
{
return $this->hasOne(Tweet::className(), ['id' => 'tweet_id']);
}
Table hashtag
public function getTweetHashtags()
{
return $this->hasMany(TweetHashtag::className(), ['hashtag_text' => 'text']);
}
public function getTweets()
{
return $this->hasMany(Tweet::className(), ['id' => 'tweet_id'])->viaTable('tweet_hashtag', ['hashtag_text' => 'text']);
}
When i try
Tweet::find()->with('hashtag')->where(['id' => $tweetID])->all()
there is Exception
Exception 'yii\base\InvalidParamException' with message 'app\models\Tweet has no relation named "hashtag".'
How I can correctly made eagre loading. To get 'text' from hashtag table, by id in Tweet table.
You should use the name or relation
Tweet::find()->with('tweetHashtags')->where(['id' => $tweetID])->all()
I have model Campaigns
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\CampaignsTargetGeo;
use App\CampaignsTargetCategory;
class Campaigns extends Model
{
const DEFAULT_MARGINALITY = 1.2;
protected $table = 'campaigns';
public $fillable = [
'name',
'url',
'user_rate_min',
'user_rate_max',
'network_rate_min',
'network_rate_max',
'daily_limit',
'hourly_limit',
'status_id',
'user_id'
];
and seed CampaignsSeeder
<?php
use Illuminate\Database\Seeder;
use App\Campaigns;
class CampaignsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run() {
$campaigns = \DB::table('campaigns')->insert([
'id' => 1,
'name' => 'test campaign',
'url' => 'http://example.com?test=true',
'user_rate_min' => '80',
'user_rate_max' => '100',
'network_rate_min' => '100',
'network_rate_max' => '120',
'daily_limit' => '10000',
'hourly_limit' => '1000',
'status_id' => '1',
'user_id' => '1'
]);
}
}
and database seeder class
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Model::unguard();
$this->call('UserSeeder');
$this->call('DictionariesTargetGeoSeeder');
$this->call('DictionariesTargetCategoriesSeeder');
$this->call('DictionariesCampaignStatusesSeeder');
$this->call('CampaignsSeeder');
Model::reguard();
}
}
when I run php artisan db:seed, I have this error
➜ panel git:(master) ✗ pa db:seed
Seeded: UserSeeder
Seeded: DictionariesTargetGeoSeeder
Seeded: DictionariesTargetCategoriesSeeder
Seeded: DictionariesCampaignStatusesSeeder
[Illuminate\Database\QueryException]
SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "campaigns" does not exist LINE 1: insert into "campaigns" ("id", "name", "url", "user_rate_min... ^ (SQL: insert into "campaigns" ("id", "name", "url", "user_rate_min", "user_rate_max", "network_rate_min", "network_rate_max", "daily_limit", "hourly_limit", "status_id", "user_id") values (1, test campaign, http://example.com80test=true, 100, 100, 120, 10000, 1000, 1, 1, ?))
[PDOException]
SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "campaigns" does not exist LINE 1: insert into "campaigns" ("id", "name", "url", "user_rate_min...
^
But table exists! I check in psql console. May transaction not commit in this moment?
If I ran ➜ panel git:(master) ✗ php artisan db:seed --class=CampaignsSeeder it works correctly
Why? :-)
insert() method expects an array of arrays (one array per row) but you are inserting one single array. Try with
$campaigns = \DB::table('campaigns')->insert([
[
'id' => 1,
'name' => 'test campaign',
'url' => 'http://example.com?test=true',
'user_rate_min' => '80',
'user_rate_max' => '100',
'network_rate_min' => '100',
'network_rate_max' => '120',
'daily_limit' => '10000',
'hourly_limit' => '1000',
'status_id' => '1',
'user_id' => '1'
]
]);