How to populate database with pre-set data? [closed] - laravel

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I am trying to run finished web app but it gives me error which is almost certainly due to app trying to find out which language version to use. I've done succesful migration but all tables (country, language etc. ) are empty. How do I populate them with data the app is looking for?

You can create default items as part of your migrations.
public function up()
{
Schema::create('users', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
});
$user = new App\User;
$user->name = 'Bob';
$user->save();
}
You can also build seeders.

There is a default DatabaseSeeder class included in a freshly installed Laravel app. It allows you to insert data to the database. Look for it in the database/seeds directory:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
}
}
If you want to add data to the countries table, write it like this:
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('countries)->insert([
'code' => 'fra',
'name' => 'France',
]);
}
}
Then use the db:seed command to seed your database:
php artisan db:seed
That's it.
You can also create your own Seeders, for example a ProductionDatabaseSeeder or a DummyDataSeeder, auto run your seeders when you migrate a database or even use model factories to easily generate dummy data. See more in the laravel docs.

I decided to go with the approach of using the migration, so that the database will be filled with the data I need straight immediately after the rows themselves are created. However, instead of adding each record individually as in ceejayoz's answer, I found it more efficient to use mass assignment functions:
class CreateManufacturersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->string("slug")->unique();
$table->string("name");
$table->timestamps();
});
Manufacturer::firstOrCreate(
["slug" => "bob", "name" => "Bob"]
);
Manufacturer::firstOrCreate(
["slug" => "alice", "name" => "Alice"]
);
Manufacturer::firstOrCreate(
["slug" => "hashim", "name" => "Hashim"]
);
}
The firstOrCreate() method saves you from needing to create a new instance of the model as well as persisting every record that you just created.

Related

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax error when seeding data to db

I am getting this error when I try to seed data into the database. I have the bookings table and a bookings package table, seeder, factory and models, and also a pivot table that links them.
here is my bookingpackage seeder
<?php
namespace Database\Seeders;
use App\Models\bookingpackage;
use Illuminate\Database\Seeder;
class BookingpackageSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
bookingpackage::create(['package_name'=>'Dj and Full Sound System',
'package_description'=>'Dj and Full Sound System.Dj and Full Sound System',
'package_price'=>'sh 80,000']);
}
}
here's bookingseeder
$fullpackage=bookingpackage::where('package_name','Dj and Full Sound System',
'package_description','Dj and Full Sound System.Dj and Full Sound System',
'package_price','sh 80,000')->first();
$fullsetpackage=Bookings::create([
'full_name'=>'Best Promoters',
'location'=>'Nairobi',
'phone'=>'0792492584',
'is_booking'=>2,
'package_id'=>1,
'email'=>'Werupromoter#admin.com',
'date'=>'07/02/2021',
'event_id'=>'5',
'event_details'=>'we would like to book you for a wedding'
]);
$fullpackage->bookingpack()->attach($fullsetpackage);
my bookingpackages table looks like this
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBookingpackagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('bookingpackages', function (Blueprint $table) {
$table->id();
$table->string('package_name');
$table->text('package_description');
$table->string('package_price');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('bookingpackages');
}
}
where might have I gone wrong in my code.
The title is very vague but i think error is in this line
$fullpackage->bookingpack()->attach($fullsetpackage);
first check bookingpack() method is exist in Bookings model
and then modify this line with:
$fullpackage->bookingpack()->attach($fullsetpackage->id);
after that replace first query in bookingseeder with:
$fullpackage=bookingpackage::where("package_name", 'Dj and Full Sound System')
->where("package_description", "Dj and Full Sound System.Dj and Full Sound System")
->where("package_price", "sh 80,000")
->first();
or you can write "where" query another way like:
$fullpackage=bookingpackage::where([
['package_name', "=", 'Dj and Full Sound System'],
['package_description', "=", 'Dj and Full Sound System.Dj and Full Sound System'],
['package_price', "=", 'sh 80,000'],
])->first();

Laravel & PostGres - Migration down() will not drop table (TimeScaleDB Extension)

Here is what create_facts_table looks like:
class CreateFactsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::connection('pgsql')->create('facts', function (Blueprint $table) {
$table->bigInteger('entry_id');
$table->string('tag');
$table->timestampTz('time');
$table->double('sensor_value');
$table->index(['entry_id', 'tag', 'time']);
$table->unique(['entry_id', 'tag', 'time']);
});
DB::connection('pgsql')->statement('SELECT create_hypertable(\'facts\', \'time\');');
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
// Tried both, neither would delete the table
Schema::connection('pgsql')->dropIfExists('facts');
//DB::connection('pgsql')->statement('DROP TABLE facts;');
}
}
I don't get any error from down(). I am able to login as the DB user specified in my .env file and run DROP TABLE facts.
When I run php artisan migration:fresh up() fails to create the table and throws a duplicate table error:
Duplicate table: 7 ERROR: relation "facts" already exists
After manually deleting the table, I can then run php artisan migration:fresh. I must specify connection('pgsql') as I'm using multiple databases. Semi-unrelated, but I'm using TimeScaleDB extension (hence create_hypertable())
I dug a bit deeper on this recently. I hadn't directly mentioned I was using the TimeScaleDB extension ('SELECT create_hypertable(\'facts\', \'time\');').
I updated the title of the question incase someone lands here from Google in the future.
Here is what I have learned:
When php artisan migration:fresh is run, it attempts to drop all tables in batch and does not use the down() method. TimeScaleDB hypertables cannot be deleted in batch.
The solution is to use php artisan migration:refresh instead which will run the defined drop() operations for each table.
Source: https://stackoverflow.com/a/69105447/5449796

Wrong migration called

I have 2 migrations, the first one has the following name 2019_11_06_171637_create_settings_table.php and structure:
class CreateSettingsTable extends Migration
{
public function up()
{
Schema::create('settings', function (Blueprint $table) {
//code
});
}
//function down
}
the second one has the following name 2020_07_08_246856_create_settings_table.php and structure:
class CreateAnotherSettingsTable extends Migration
{
public function up()
{
Schema::create('another_settings', function (Blueprint $table) {
//code
});
}
//function down
}
When I run php artisan migrate all migrations going well until Migrating: 2020_07_08_246856_create_settings_table - it's trying to run the previos migration(2019_11_06_171637_create_settings_table.php) and fire an exception Table 'settings' already exists.
Does this mean that the name of the migration file must be unique after the date and numbers?
I've read somewhere that Laravel uses the filenames of migrations to call the correct class for the migration. I've tried to look up some documentation or reference on this, but I can't find it anymore. You currently have the same filename twice (if you ignore the timestamp part) which results in Laravel calling the same class twice.
If you rename the second file (the one with the CreateAnotherSettingsTable class) to 2020_07_08_246856_create_another_settings_table.php, your problem will be fixed.
I found this very interesting so I looked within the source code.
\Illuminate\Database\Console\Migrations\TableGuesser will use the migration name to determine whether if the table already exists.
// Next, we will attempt to guess the table name if this the migration has
// "create" in the name. This will allow us to provide a convenient way
// of creating migrations that create new tables for the application.
if (! $table) {
[$table, $create] = TableGuesser::guess($name);
}
This is executed upon artisan:make and migrate:install commands.
So ultimately, as your migration file name is create_settings_table.php, the "settings" word is what will be used for checking.
The code that laravel uses for this determination is:
const CREATE_PATTERNS = [
'/^create_(\w+)_table$/',
'/^create_(\w+)$/',
];
const CHANGE_PATTERNS = [
'/_(to|from|in)_(\w+)_table$/',
'/_(to|from|in)_(\w+)$/',
];
/**
* Attempt to guess the table name and "creation" status of the given migration.
*
* #param string $migration
* #return array
*/
public static function guess($migration)
{
foreach (self::CREATE_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[1], $create = true];
}
}
foreach (self::CHANGE_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[2], $create = false];
}
}
}
So your solution is to rename one of those migration files.
CreateAnotherSettingsTable will be the best, standard following, name

How to normalize a table when I have a key pair type of data

I am making a platform where a trainer will be able to add courses to his profile. But before he adds course there needs to be an application acceptance that needs to be done.
So, I had earlier divided my database into three parts:
users | trainer | course
After a little bit of research, I found that I will have to do database normalization but I am having issues with setting it up.
Now I have trainer table trainer_experience table and trainer_achievements table. Inside trainer experience table I have to save data of the position they wore in and the company name.
My trainer table is this:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTrainersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('trainers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->date('date_of_birth');
$table->integer('mobile_number');
$table->longText('address');
$table->string('id_proof');
$table->string('id_registration_number');
$table->string('high_school_name');
$table->string('graduation_college_name');
$table->string('graduation_course_name');
$table->string('post_graduation_college_name');
$table->string('post_graduation_course_name');
$table->string('phd_field_of_study');
$table->string('total_duration_of_training');
$table->integer('no_of_people_trained');
$table->boolean('paid_training');
$table->string('training_category');
$table->string('course_material_ready');
$table->string('youtube_link')->nullable();
$table->string('twitter_link')->nullable();
$table->string('instagram_link')->nullable();
$table->string('facebook_link')->nullable();
$table->string('linkedin_link')->nullable();
$table->string('blog_link')->nullable();
$table->string('website_link')->nullable();
$table->string('meetup_group_link')->nullable();
$table->timestamps();
$table->index('user_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('trainers');
}
}
How do I store the data so, that I can at least retrieve it in the order they have entered? Do I need to make two different tables? What is the best option that I have?
You have to figure out in the data in trainer_experience and trainer_achievements is reusable or not ?
trainer_experience and trainer_achievements are dependent on each other?
Use Polymorphic relationship for best use.

Laravel: renaming database table breaks functionality

I'm still quite new to Laravel, Eloquent and Artisan.
What I'm trying to do is pretty easy: I want to create a new Eloquent model AboutUs, along with a migration file to create the table about_us.
I run the following command:
PHP artisan make:model AboutUs -m
This generates the model and migration file, however, the migration file is named '2017_07_18_211959_create_about_uses_table.php', automatically adding the unnecessary 'es' to 'us', and creating a table 'aboutuses' instead of 'about_us'.
If I manually change the migration file like so:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAboutUsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('about_us', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->boolean('active');
$table->string('title')->nullable();
$table->text('text')->nullable();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('about_us');
}
}
The model like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class AboutUs extends Model
{
protected $fillable = ['id', 'active', 'title', 'text'];
public static function getAboutUs()
{
return AboutUs::find(1);
}
public function postAboutUs($session, $active, $title, $text)
{
$aboutUs = $session->get('about_us');
array_push($aboutUs, ['active' => $active, 'title' => $title, 'text' => $text,]);
$session->put('about_us', $aboutUs);
}
}
Then run the migration:
PHP artisan migrate
The database table 'about_us' is created correctly, but when I insert a row in the table and attempt to use getAboutUs, it crashes, the laravel.log stating that:
local.ERROR: exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ID226233_db.aboutuses' doesn't exist' in C:\PHP Projects\xxx\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:77
I can see that there are still references to "aboutuses" in the autoload_classmap and autoload_static files. Changing this manually doesn't fix the issue, nor does running:
composer dump autoload
Next, I tried to simply not rename the table, but run the migration to create the initial "aboutuses" table. This fixed the functionality, as the model now works correctly. However, if I now add a new migration with:
Schema::rename('aboutuses', 'about_us');
This renames the table in the DB, but not in the autoload files or wherever else, resulting in broken functionality.
Surely there must be an easier way to either:
create a model with migration file with a FIXED name, instead of it
automatically changing the name by adding an unnecessary suffix.
rename a model and change the necessary files to prevent the model
from breaking.
Could anyone point me in the right direction before I lose my mind over this? :)
You can specify a custom table name in your Eloquent model class. Here is the example from the docs:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'my_flights';
}
Source: https://laravel.com/docs/5.4/eloquent#eloquent-model-conventions
Hope that helps.

Resources